3 * Unix SMB/Netbios implementation.
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 * Copyright (C) Hewlett-Packard Company 1999.
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.
28 extern int DEBUGLEVEL
;
30 extern fstring global_myworkgroup
;
31 extern pstring global_myname
;
32 extern DOM_SID global_sam_sid
;
34 extern rid_name domain_group_rids
[];
35 extern rid_name domain_alias_rids
[];
36 extern rid_name builtin_alias_rids
[];
38 /*******************************************************************
39 This next function should be replaced with something that
40 dynamically returns the correct user info..... JRA.
41 ********************************************************************/
43 static BOOL
get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
,
45 int *total_entries
, int *num_entries
,
50 struct sam_passwd
*pwd
= NULL
;
55 if (pw_buf
== NULL
) return False
;
57 vp
= startsmbpwent(False
);
59 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
63 while (((pwd
= getsam21pwent(vp
)) != NULL
) && (*num_entries
) < max_num_entries
) {
67 /* skip the requested number of entries.
68 not very efficient, but hey...
74 user_name_len
= strlen(pwd
->smb_name
);
75 init_unistr2(&(pw_buf
[(*num_entries
)].uni_user_name
), pwd
->smb_name
, user_name_len
);
76 init_uni_hdr(&(pw_buf
[(*num_entries
)].hdr_user_name
), user_name_len
);
77 pw_buf
[(*num_entries
)].user_rid
= pwd
->user_rid
;
78 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
80 /* Now check if the NT compatible password is available. */
81 if (pwd
->smb_nt_passwd
!= NULL
) {
82 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pwd
->smb_nt_passwd
, 16);
85 pw_buf
[(*num_entries
)].acb_info
= (uint16
)pwd
->acct_ctrl
;
87 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
88 (*num_entries
), pwd
->smb_name
,
89 pwd
->user_rid
, pwd
->acct_ctrl
));
91 if (acb_mask
== 0 || (pwd
->acct_ctrl
& acb_mask
)) {
92 DEBUG(5,(" acb_mask %x accepts\n", acb_mask
));
95 DEBUG(5,(" acb_mask %x rejects\n", acb_mask
));
103 return (*num_entries
) > 0;
106 /*******************************************************************
107 This function uses the username map file and tries to map a UNIX
108 user name to an DOS name. (Sort of the reverse of the
109 map_username() function.) Since more than one DOS name can map
110 to the UNIX name, to reverse the mapping you have to specify
111 which corresponding DOS name you want; that's where the name_idx
112 parameter comes in. Returns the string requested or NULL if it
113 fails or can't complete the request for any reason. This doesn't
114 handle group names (starting with '@') or names starting with
115 '+' or '&'. If they are encountered, they are skipped.
116 ********************************************************************/
118 static char *unmap_unixname(char *unix_user_name
, int name_idx
)
120 char *mapfile
= lp_username_map();
125 if (!*unix_user_name
) return NULL
;
126 if (!*mapfile
) return NULL
;
128 lines
= file_lines_load(mapfile
, NULL
);
130 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile
));
134 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile
, name_idx
));
136 for (i
=0; lines
[i
]; i
++) {
137 char *unixname
= lines
[i
];
138 char *dosname
= strchr(unixname
,'=');
145 while (isspace(*unixname
))
147 if ('!' == *unixname
) {
149 while (*unixname
&& isspace(*unixname
))
153 if (!*unixname
|| strchr("#;",*unixname
))
156 if (strncmp(unixname
, unix_user_name
, strlen(unix_user_name
)))
159 /* We have matched the UNIX user name */
161 while(next_token(&dosname
, tok
, LIST_SEP
, sizeof(tok
))) {
162 if (!strchr("@&+", *tok
)) {
171 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
172 file_lines_free(lines
);
175 file_lines_free(lines
);
180 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
181 file_lines_free(lines
);
185 /*******************************************************************
186 This function sets up a list of users taken from the list of
187 users that UNIX knows about, as well as all the user names that
188 Samba maps to a valid UNIX user name. (This should work with
190 ********************************************************************/
192 static BOOL
get_passwd_entries(SAM_USER_INFO_21
*pw_buf
,
194 int *total_entries
, int *num_entries
,
198 static struct passwd
*pwd
= NULL
;
199 static uint32 pw_rid
;
200 static BOOL orig_done
= False
;
201 static int current_idx
= 0;
202 static int mapped_idx
= 0;
205 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
208 (*total_entries
) = 0;
210 if (pw_buf
== NULL
) return False
;
212 if (current_idx
== 0) {
216 /* These two cases are inefficient, but should be called very rarely */
217 /* they are the cases where the starting index isn't picking up */
218 /* where we left off last time. It is efficient when it starts over */
219 /* at zero though. */
220 if (start_idx
> current_idx
) {
221 /* We aren't far enough; advance to start_idx */
222 while (current_idx
< start_idx
) {
226 if ((pwd
= getpwent()) == NULL
) break;
231 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
232 (current_idx
< start_idx
)) {
237 if (unmap_name
== NULL
) {
242 } else if (start_idx
< current_idx
) {
243 /* We are already too far; start over and advance to start_idx */
249 while (current_idx
< start_idx
) {
253 if ((pwd
= getpwent()) == NULL
) break;
258 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
259 (current_idx
< start_idx
)) {
264 if (unmap_name
== NULL
) {
271 sep
= lp_winbind_separator();
273 /* now current_idx == start_idx */
274 while ((*num_entries
) < max_num_entries
) {
278 /* This does the original UNIX user itself */
280 if ((pwd
= getpwent()) == NULL
) break;
282 /* Don't enumerate winbind users as they are not local */
284 if (strchr(pwd
->pw_name
, *sep
) != NULL
) {
288 user_name_len
= strlen(pwd
->pw_name
);
289 pw_rid
= pdb_uid_to_user_rid(pwd
->pw_uid
);
290 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
291 init_unistr2(&(pw_buf
[(*num_entries
)].uni_user_name
), pwd
->pw_name
, user_name_len
);
292 init_uni_hdr(&(pw_buf
[(*num_entries
)].hdr_user_name
), user_name_len
);
293 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
294 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
296 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
298 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
306 /* This does all the user names that map to the UNIX user */
307 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
308 (*num_entries
< max_num_entries
)) {
309 user_name_len
= strlen(unmap_name
);
310 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
311 init_unistr2(&(pw_buf
[(*num_entries
)].uni_user_name
), unmap_name
, user_name_len
);
312 init_uni_hdr(&(pw_buf
[(*num_entries
)].hdr_user_name
), user_name_len
);
313 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
314 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
316 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
318 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
326 if (unmap_name
== NULL
) {
327 /* done with 'aliases', go on to next UNIX user */
334 /* totally done, reset everything */
340 return (*num_entries
) > 0;
343 /*******************************************************************
345 ********************************************************************/
346 static BOOL
samr_reply_close_hnd(SAMR_Q_CLOSE_HND
*q_u
,
349 SAMR_R_CLOSE_HND r_u
;
351 /* set up the SAMR unknown_1 response */
352 memset((char *)r_u
.pol
.data
, '\0', POL_HND_SIZE
);
354 /* close the policy handle */
355 if (close_lsa_policy_hnd(&(q_u
->pol
)))
361 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID
;
364 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
366 /* store the response in the SMB stream */
367 if(!samr_io_r_close_hnd("", &r_u
, rdata
, 0))
370 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
375 /*******************************************************************
377 ********************************************************************/
378 static BOOL
api_samr_close_hnd(pipes_struct
*p
)
380 SAMR_Q_CLOSE_HND q_u
;
381 prs_struct
*data
= &p
->in_data
.data
;
382 prs_struct
*rdata
= &p
->out_data
.rdata
;
384 /* grab the samr unknown 1 */
385 if(!samr_io_q_close_hnd("", &q_u
, data
, 0))
388 /* construct reply. always indicate success */
389 if(!samr_reply_close_hnd(&q_u
, rdata
))
396 /*******************************************************************
397 samr_reply_open_domain
398 ********************************************************************/
399 static BOOL
samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN
*q_u
,
402 SAMR_R_OPEN_DOMAIN r_u
;
403 BOOL pol_open
= False
;
407 /* find the connection policy handle. */
408 if (r_u
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->connect_pol
)) == -1))
410 r_u
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
413 /* get a (unique) handle. open a policy on it. */
414 if (r_u
.status
== 0x0 && !(pol_open
= open_lsa_policy_hnd(&(r_u
.domain_pol
))))
416 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
419 /* associate the domain SID with the (unique) handle. */
420 if (r_u
.status
== 0x0 && !set_lsa_policy_samr_sid(&(r_u
.domain_pol
), &(q_u
->dom_sid
.sid
)))
422 /* oh, whoops. don't know what error message to return, here */
423 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
426 if (r_u
.status
!= 0 && pol_open
)
428 close_lsa_policy_hnd(&(r_u
.domain_pol
));
431 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
433 /* store the response in the SMB stream */
434 if(!samr_io_r_open_domain("", &r_u
, rdata
, 0))
437 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
442 /*******************************************************************
444 ********************************************************************/
445 static BOOL
api_samr_open_domain(pipes_struct
*p
)
447 SAMR_Q_OPEN_DOMAIN q_u
;
448 prs_struct
*data
= &p
->in_data
.data
;
449 prs_struct
*rdata
= &p
->out_data
.rdata
;
451 /* grab the samr open */
452 if(!samr_io_q_open_domain("", &q_u
, data
, 0))
455 /* construct reply. always indicate success */
456 if(!samr_reply_open_domain(&q_u
, rdata
))
463 /*******************************************************************
464 samr_reply_unknown_2c
465 ********************************************************************/
466 static BOOL
samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C
*q_u
,
469 SAMR_R_UNKNOWN_2C r_u
;
472 /* find the policy handle. open a policy on it. */
473 if (status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->user_pol
)) == -1))
475 status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
478 /* find the user's rid */
479 if ((status
== 0x0) && (get_lsa_policy_samr_rid(&(q_u
->user_pol
)) == 0xffffffff))
481 status
= NT_STATUS_OBJECT_TYPE_MISMATCH
;
484 init_samr_r_unknown_2c(&r_u
, status
);
486 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__
));
488 /* store the response in the SMB stream */
489 if(!samr_io_r_unknown_2c("", &r_u
, rdata
, 0))
492 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__
));
497 /*******************************************************************
499 ********************************************************************/
500 static BOOL
api_samr_unknown_2c(pipes_struct
*p
)
502 SAMR_Q_UNKNOWN_2C q_u
;
503 prs_struct
*data
= &p
->in_data
.data
;
504 prs_struct
*rdata
= &p
->out_data
.rdata
;
506 /* grab the samr open */
507 if(!samr_io_q_unknown_2c("", &q_u
, data
, 0))
510 /* construct reply. always indicate success */
511 if(!samr_reply_unknown_2c(&q_u
, rdata
))
518 /*******************************************************************
520 ********************************************************************/
521 static BOOL
samr_reply_unknown_3(SAMR_Q_UNKNOWN_3
*q_u
,
524 SAMR_R_UNKNOWN_3 r_u
;
525 DOM_SID3 sid
[MAX_SAM_SIDS
];
531 /* find the policy handle. open a policy on it. */
532 if (status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->user_pol
)) == -1))
534 status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
537 /* find the user's rid */
538 if (status
== 0x0 && (rid
= get_lsa_policy_samr_rid(&(q_u
->user_pol
))) == 0xffffffff)
540 status
= NT_STATUS_OBJECT_TYPE_MISMATCH
;
546 DOM_SID everyone_sid
;
548 user_sid
= global_sam_sid
;
550 SMB_ASSERT_ARRAY(user_sid
.sub_auths
, user_sid
.num_auths
+1);
555 user_sid
.sub_auths
[user_sid
.num_auths
++] = rid
;
557 string_to_sid(&everyone_sid
, "S-1-1");
559 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
560 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
561 init_dom_sid3(&(sid
[0]), 0x035b, 0x0002, &everyone_sid
);
562 init_dom_sid3(&(sid
[1]), 0x0044, 0x0002, &user_sid
);
565 init_samr_r_unknown_3(&r_u
,
567 0x00000014, 0x0002, 0x0070,
570 DEBUG(5,("samr_unknown_3: %d\n", __LINE__
));
572 /* store the response in the SMB stream */
573 if(!samr_io_r_unknown_3("", &r_u
, rdata
, 0))
576 DEBUG(5,("samr_unknown_3: %d\n", __LINE__
));
581 /*******************************************************************
583 ********************************************************************/
584 static BOOL
api_samr_unknown_3(pipes_struct
*p
)
586 SAMR_Q_UNKNOWN_3 q_u
;
587 prs_struct
*data
= &p
->in_data
.data
;
588 prs_struct
*rdata
= &p
->out_data
.rdata
;
590 /* grab the samr open */
591 if(!samr_io_q_unknown_3("", &q_u
, data
, 0))
594 /* construct reply. always indicate success */
595 if(!samr_reply_unknown_3(&q_u
, rdata
))
602 /*******************************************************************
603 samr_reply_enum_dom_users
604 ********************************************************************/
605 static BOOL
samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS
*q_u
,
608 SAMR_R_ENUM_DOM_USERS r_e
;
609 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
614 r_e
.total_num_entries
= 0;
616 /* find the policy handle. open a policy on it. */
617 if (r_e
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
619 r_e
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
622 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__
));
625 get_sampwd_entries(pass
, 0, &total_entries
, &num_entries
, MAX_SAM_ENTRIES
, q_u
->acb_mask
);
628 init_samr_r_enum_dom_users(&r_e
, total_entries
,
629 q_u
->unknown_0
, num_entries
,
632 /* store the response in the SMB stream */
633 if(!samr_io_r_enum_dom_users("", &r_e
, rdata
, 0))
636 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__
));
641 /*******************************************************************
642 api_samr_enum_dom_users
643 ********************************************************************/
644 static BOOL
api_samr_enum_dom_users(pipes_struct
*p
)
646 SAMR_Q_ENUM_DOM_USERS q_e
;
647 prs_struct
*data
= &p
->in_data
.data
;
648 prs_struct
*rdata
= &p
->out_data
.rdata
;
650 /* grab the samr open */
651 if(!samr_io_q_enum_dom_users("", &q_e
, data
, 0))
654 /* construct reply. */
655 if(!samr_reply_enum_dom_users(&q_e
, rdata
))
661 /*******************************************************************
662 samr_reply_enum_dom_groups
663 ********************************************************************/
664 static BOOL
samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS
*q_u
,
667 SAMR_R_ENUM_DOM_GROUPS r_e
;
668 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
671 char *dummy_group
= "Domain Admins";
676 /* find the policy handle. open a policy on it. */
677 if (r_e
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
679 r_e
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
682 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
686 ZERO_STRUCTP(&pass
[0]);
687 init_unistr2(&(pass
[0].uni_user_name
), dummy_group
, strlen(dummy_group
));
688 pass
[0].user_rid
= DOMAIN_GROUP_RID_ADMINS
;
690 if (r_e
.status
== 0 && got_grps
)
692 init_samr_r_enum_dom_groups(&r_e
, q_u
->start_idx
, num_entries
, pass
, r_e
.status
);
695 /* store the response in the SMB stream */
696 if(!samr_io_r_enum_dom_groups("", &r_e
, rdata
, 0))
699 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
704 /*******************************************************************
705 api_samr_enum_dom_groups
706 ********************************************************************/
707 static BOOL
api_samr_enum_dom_groups(pipes_struct
*p
)
709 SAMR_Q_ENUM_DOM_GROUPS q_e
;
710 prs_struct
*data
= &p
->in_data
.data
;
711 prs_struct
*rdata
= &p
->out_data
.rdata
;
713 /* grab the samr open */
714 if(!samr_io_q_enum_dom_groups("", &q_e
, data
, 0))
717 /* construct reply. */
718 if(!samr_reply_enum_dom_groups(&q_e
, rdata
))
724 /*******************************************************************
725 samr_reply_enum_dom_aliases
726 ********************************************************************/
727 static BOOL
samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES
*q_u
,
730 SAMR_R_ENUM_DOM_ALIASES r_e
;
731 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
740 /* find the policy handle. open a policy on it. */
741 if (r_e
.status
== 0x0 && !get_lsa_policy_samr_sid(&q_u
->pol
, &sid
))
743 r_e
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
746 sid_to_string(sid_str
, &sid
);
747 sid_to_string(sam_sid_str
, &global_sam_sid
);
749 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
751 /* well-known aliases */
752 if (strequal(sid_str
, "S-1-5-32"))
755 while (num_entries
< MAX_SAM_ENTRIES
&& ((name
= builtin_alias_rids
[num_entries
].name
) != NULL
))
757 init_unistr2(&(pass
[num_entries
].uni_user_name
), name
, strlen(name
));
758 pass
[num_entries
].user_rid
= builtin_alias_rids
[num_entries
].rid
;
762 else if (strequal(sid_str
, sam_sid_str
))
767 sep
= lp_winbind_separator();
770 /* we return the UNIX groups here. This seems to be the right */
771 /* thing to do, since NT member servers return their local */
772 /* groups in the same situation. */
775 while (num_entries
< MAX_SAM_ENTRIES
&& ((grp
= getgrent()) != NULL
))
779 /* Don't return winbind groups as they are not local! */
781 if (strchr(name
, *sep
) != NULL
) {
785 init_unistr2(&(pass
[num_entries
].uni_user_name
), name
, strlen(name
));
786 pass
[num_entries
].user_rid
= pdb_gid_to_group_rid(grp
->gr_gid
);
793 init_samr_r_enum_dom_aliases(&r_e
, num_entries
, pass
, r_e
.status
);
795 /* store the response in the SMB stream */
796 if(!samr_io_r_enum_dom_aliases("", &r_e
, rdata
, 0))
799 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
804 /*******************************************************************
805 api_samr_enum_dom_aliases
806 ********************************************************************/
807 static BOOL
api_samr_enum_dom_aliases(pipes_struct
*p
)
809 SAMR_Q_ENUM_DOM_ALIASES q_e
;
810 prs_struct
*data
= &p
->in_data
.data
;
811 prs_struct
*rdata
= &p
->out_data
.rdata
;
815 /* grab the samr open */
816 if(!samr_io_q_enum_dom_aliases("", &q_e
, data
, 0))
819 /* construct reply. */
820 if(!samr_reply_enum_dom_aliases(&q_e
, rdata
))
827 /*******************************************************************
828 samr_reply_query_dispinfo
829 ********************************************************************/
830 static BOOL
samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO
*q_u
, prs_struct
*rdata
)
832 SAMR_R_QUERY_DISPINFO r_e
;
836 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
838 int total_entries
= 0;
840 uint16 switch_level
= 0x0;
844 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__
));
846 /* find the policy handle. open a policy on it. */
847 if (r_e
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
849 r_e
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
850 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
853 if (r_e
.status
== 0x0)
855 /* decide how many entries to get depending on the max_entries
856 and max_size passed by client */
859 if(q_u
->max_entries
> MAX_SAM_ENTRIES
)
860 q_u
->max_entries
= MAX_SAM_ENTRIES
;
862 retsize
= (q_u
->max_entries
* (sizeof(SAM_ENTRY1
)+sizeof(SAM_STR1
)))
865 if(retsize
> q_u
->max_size
)
867 /* determine max_entries based on max_size */
868 q_u
->max_entries
= (q_u
->max_size
- 3*sizeof(uint32
)) /
869 (sizeof(SAM_ENTRY1
)+sizeof(SAM_STR1
));
870 q_u
->max_entries
= (q_u
->max_entries
>0?q_u
->max_entries
:1);
873 DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u
->max_entries
));
876 got_pwds
= get_passwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
, q_u
->max_entries
, 0);
879 /* more left - set resume handle */
880 if(total_entries
> num_entries
)
885 switch (q_u
->switch_level
)
890 /* query disp info is for users */
893 init_sam_info_1(&info1
, ACB_NORMAL
,
894 q_u
->start_idx
, num_entries
, pass
);
896 ctr
.sam
.info1
= &info1
;
902 /* query disp info is for servers */
905 init_sam_info_2(&info2
, ACB_WSTRUST
,
906 q_u
->start_idx
, num_entries
, pass
);
908 ctr
.sam
.info2
= &info2
;
915 /* more left - set resume handle */
916 if(total_entries
> num_entries
)
921 if (r_e
.status
== 0 || r_e
.status
== 0x105)
923 init_samr_r_query_dispinfo(&r_e
, switch_level
, &ctr
, r_e
.status
);
926 /* store the response in the SMB stream */
927 if(!samr_io_r_query_dispinfo("", &r_e
, rdata
, 0))
930 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__
));
935 /*******************************************************************
936 api_samr_query_dispinfo
937 ********************************************************************/
938 static BOOL
api_samr_query_dispinfo(pipes_struct
*p
)
940 SAMR_Q_QUERY_DISPINFO q_e
;
941 prs_struct
*data
= &p
->in_data
.data
;
942 prs_struct
*rdata
= &p
->out_data
.rdata
;
944 /* grab the samr open */
945 if(!samr_io_q_query_dispinfo("", &q_e
, data
, 0))
948 /* construct reply. */
949 if(!samr_reply_query_dispinfo(&q_e
, rdata
))
956 /*******************************************************************
957 samr_reply_query_aliasinfo
958 ********************************************************************/
959 static BOOL
samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO
*q_u
,
962 SAMR_R_QUERY_ALIASINFO r_e
;
963 fstring alias_desc
= "Local Unix group";
970 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__
));
972 /* find the policy handle. open a policy on it. */
973 if (r_e
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
975 r_e
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
978 alias_rid
= get_lsa_policy_samr_rid(&q_u
->pol
);
979 if(alias_rid
== 0xffffffff)
980 r_e
.status
= 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS
;
982 if(!local_lookup_rid(alias_rid
, alias
, &type
))
984 r_e
.status
= 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS
;
987 init_samr_r_query_aliasinfo(&r_e
, q_u
->switch_level
, alias
, alias_desc
);
989 /* store the response in the SMB stream */
990 if(!samr_io_r_query_aliasinfo("", &r_e
, rdata
, 0))
993 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__
));
998 /*******************************************************************
999 api_samr_query_aliasinfo
1000 ********************************************************************/
1001 static BOOL
api_samr_query_aliasinfo(pipes_struct
*p
)
1003 SAMR_Q_QUERY_ALIASINFO q_e
;
1004 prs_struct
*data
= &p
->in_data
.data
;
1005 prs_struct
*rdata
= &p
->out_data
.rdata
;
1007 /* grab the samr open */
1008 if(!samr_io_q_query_aliasinfo("", &q_e
, data
, 0))
1011 /* construct reply. */
1012 if(!samr_reply_query_aliasinfo(&q_e
, rdata
))
1019 /*******************************************************************
1020 samr_reply_lookup_ids
1021 ********************************************************************/
1022 static BOOL
samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS
*q_u
,
1025 uint32 rid
[MAX_SAM_ENTRIES
];
1027 int num_rids
= q_u
->num_sids1
;
1029 SAMR_R_LOOKUP_IDS r_u
;
1031 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__
));
1033 if (num_rids
> MAX_SAM_ENTRIES
)
1035 num_rids
= MAX_SAM_ENTRIES
;
1036 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids
));
1041 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1043 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1045 struct sam_passwd
*sam_pass
;
1049 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1050 q_u
->uni_user_name
[i
].uni_str_len
));
1052 /* find the user account */
1054 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1057 if (sam_pass
== NULL
)
1059 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1064 rid
[i
] = sam_pass
->user_rid
;
1070 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1072 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, status
);
1074 /* store the response in the SMB stream */
1075 if(!samr_io_r_lookup_ids("", &r_u
, rdata
, 0))
1078 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__
));
1083 /*******************************************************************
1085 ********************************************************************/
1086 static BOOL
api_samr_lookup_ids(pipes_struct
*p
)
1088 SAMR_Q_LOOKUP_IDS q_u
;
1089 prs_struct
*data
= &p
->in_data
.data
;
1090 prs_struct
*rdata
= &p
->out_data
.rdata
;
1092 /* grab the samr 0x10 */
1093 if(!samr_io_q_lookup_ids("", &q_u
, data
, 0))
1096 /* construct reply. always indicate success */
1097 if(!samr_reply_lookup_ids(&q_u
, rdata
))
1103 /*******************************************************************
1104 samr_reply_lookup_names
1105 ********************************************************************/
1107 static BOOL
samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES
*q_u
,
1110 uint32 rid
[MAX_SAM_ENTRIES
];
1111 uint8 type
[MAX_SAM_ENTRIES
];
1114 int num_rids
= q_u
->num_names1
;
1117 SAMR_R_LOOKUP_NAMES r_u
;
1119 DEBUG(5,("samr_lookup_names: %d\n", __LINE__
));
1124 if (!get_lsa_policy_samr_sid(&q_u
->pol
, &pol_sid
)) {
1125 status
= 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH
;
1126 init_samr_r_lookup_names(&r_u
, 0, rid
, type
, status
);
1127 if(!samr_io_r_lookup_names("", &r_u
, rdata
, 0)) {
1128 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1134 if (num_rids
> MAX_SAM_ENTRIES
) {
1135 num_rids
= MAX_SAM_ENTRIES
;
1136 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids
));
1139 SMB_ASSERT_ARRAY(q_u
->uni_name
, num_rids
);
1141 for (i
= 0; i
< num_rids
; i
++) {
1144 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
1146 rid
[i
] = 0xffffffff;
1147 type
[i
] = SID_NAME_UNKNOWN
;
1149 fstrcpy(name
, dos_unistrn2(q_u
->uni_name
[i
].buffer
,
1150 q_u
->uni_name
[i
].uni_str_len
));
1152 if(sid_equal(&pol_sid
, &global_sam_sid
))
1155 if(local_lookup_name(global_myname
, name
,
1158 sid_split_rid( &sid
, &rid
[i
]);
1164 init_samr_r_lookup_names(&r_u
, num_rids
, rid
, type
, status
);
1166 /* store the response in the SMB stream */
1167 if(!samr_io_r_lookup_names("", &r_u
, rdata
, 0)) {
1168 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
1172 DEBUG(5,("samr_lookup_names: %d\n", __LINE__
));
1177 /*******************************************************************
1178 api_samr_lookup_names
1179 ********************************************************************/
1181 static BOOL
api_samr_lookup_names(pipes_struct
*p
)
1183 SAMR_Q_LOOKUP_NAMES q_u
;
1184 prs_struct
*data
= &p
->in_data
.data
;
1185 prs_struct
*rdata
= &p
->out_data
.rdata
;
1187 memset(&q_u
, '\0', sizeof(q_u
));
1189 /* grab the samr lookup names */
1190 if(!samr_io_q_lookup_names("", &q_u
, data
, 0)) {
1191 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
1195 /* construct reply. always indicate success */
1196 if(!samr_reply_lookup_names(&q_u
, rdata
))
1202 /*******************************************************************
1203 samr_reply_chgpasswd_user
1204 ********************************************************************/
1206 static BOOL
samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER
*q_u
,
1209 SAMR_R_CHGPASSWD_USER r_u
;
1210 uint32 status
= 0x0;
1214 fstrcpy(user_name
, dos_unistrn2(q_u
->uni_user_name
.buffer
, q_u
->uni_user_name
.uni_str_len
));
1215 fstrcpy(wks
, dos_unistrn2(q_u
->uni_dest_host
.buffer
, q_u
->uni_dest_host
.uni_str_len
));
1217 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1219 if (!pass_oem_change(user_name
,
1220 q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1221 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1223 status
= 0xC0000000 | NT_STATUS_WRONG_PASSWORD
;
1226 init_samr_r_chgpasswd_user(&r_u
, status
);
1228 /* store the response in the SMB stream */
1229 if(!samr_io_r_chgpasswd_user("", &r_u
, rdata
, 0)) {
1230 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
1234 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__
));
1238 /*******************************************************************
1239 api_samr_chgpasswd_user
1240 ********************************************************************/
1242 static BOOL
api_samr_chgpasswd_user(pipes_struct
*p
)
1244 SAMR_Q_CHGPASSWD_USER q_u
;
1245 prs_struct
*data
= &p
->in_data
.data
;
1246 prs_struct
*rdata
= &p
->out_data
.rdata
;
1248 /* unknown 38 command */
1249 if (!samr_io_q_chgpasswd_user("", &q_u
, data
, 0)) {
1250 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
1254 /* construct reply. */
1255 if(!samr_reply_chgpasswd_user(&q_u
, rdata
)) {
1256 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
1264 /*******************************************************************
1265 samr_reply_unknown_38
1266 ********************************************************************/
1267 static BOOL
samr_reply_unknown_38(SAMR_Q_UNKNOWN_38
*q_u
, prs_struct
*rdata
)
1269 SAMR_R_UNKNOWN_38 r_u
;
1271 DEBUG(5,("samr_unknown_38: %d\n", __LINE__
));
1273 init_samr_r_unknown_38(&r_u
);
1275 /* store the response in the SMB stream */
1276 if(!samr_io_r_unknown_38("", &r_u
, rdata
, 0))
1279 DEBUG(5,("samr_unknown_38: %d\n", __LINE__
));
1283 /*******************************************************************
1285 ********************************************************************/
1286 static BOOL
api_samr_unknown_38(pipes_struct
*p
)
1288 SAMR_Q_UNKNOWN_38 q_u
;
1289 prs_struct
*data
= &p
->in_data
.data
;
1290 prs_struct
*rdata
= &p
->out_data
.rdata
;
1292 /* unknown 38 command */
1293 if(!samr_io_q_unknown_38("", &q_u
, data
, 0))
1296 /* construct reply. always indicate success */
1297 if(!samr_reply_unknown_38(&q_u
, rdata
))
1304 /*******************************************************************
1305 samr_reply_unknown_12
1306 ********************************************************************/
1307 static BOOL
samr_reply_unknown_12(SAMR_Q_UNKNOWN_12
*q_u
,
1310 fstring group_names
[MAX_SAM_ENTRIES
];
1311 uint32 group_attrs
[MAX_SAM_ENTRIES
];
1313 int num_gids
= q_u
->num_gids1
;
1315 SAMR_R_UNKNOWN_12 r_u
;
1317 DEBUG(5,("samr_unknown_12: %d\n", __LINE__
));
1319 /* find the policy handle. open a policy on it. */
1320 if (status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
1322 status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
1328 if (num_gids
> MAX_SAM_ENTRIES
)
1330 num_gids
= MAX_SAM_ENTRIES
;
1331 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids
));
1334 for (i
= 0; i
< num_gids
&& status
== 0; i
++)
1336 fstrcpy(group_names
[i
], "dummy group");
1337 group_attrs
[i
] = 0x2;
1341 init_samr_r_unknown_12(&r_u
, num_gids
, group_names
, group_attrs
, status
);
1343 /* store the response in the SMB stream */
1344 if(!samr_io_r_unknown_12("", &r_u
, rdata
, 0))
1347 DEBUG(5,("samr_unknown_12: %d\n", __LINE__
));
1352 /*******************************************************************
1354 ********************************************************************/
1355 static BOOL
api_samr_unknown_12(pipes_struct
*p
)
1357 SAMR_Q_UNKNOWN_12 q_u
;
1358 prs_struct
*data
= &p
->in_data
.data
;
1359 prs_struct
*rdata
= &p
->out_data
.rdata
;
1361 /* grab the samr lookup names */
1362 if(!samr_io_q_unknown_12("", &q_u
, data
, 0))
1365 /* construct reply. always indicate success */
1366 if(!samr_reply_unknown_12(&q_u
, rdata
))
1373 /*******************************************************************
1374 samr_reply_open_user
1375 ********************************************************************/
1376 static BOOL
samr_reply_open_user(SAMR_Q_OPEN_USER
*q_u
, prs_struct
*rdata
, int status
)
1378 SAMR_R_OPEN_USER r_u
;
1379 struct sam_passwd
*sam_pass
;
1380 BOOL pol_open
= False
;
1382 /* set up the SAMR open_user response */
1383 memset((char *)r_u
.user_pol
.data
, '\0', POL_HND_SIZE
);
1387 /* find the policy handle. open a policy on it. */
1388 if (r_u
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->domain_pol
)) == -1))
1390 r_u
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
1393 /* get a (unique) handle. open a policy on it. */
1394 if (r_u
.status
== 0x0 && !(pol_open
= open_lsa_policy_hnd(&(r_u
.user_pol
))))
1396 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1400 sam_pass
= getsam21pwrid(q_u
->user_rid
);
1403 /* check that the RID exists in our domain. */
1404 if (r_u
.status
== 0x0 && sam_pass
== NULL
)
1406 r_u
.status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1409 /* associate the RID with the (unique) handle. */
1410 if (r_u
.status
== 0x0 && !set_lsa_policy_samr_rid(&(r_u
.user_pol
), q_u
->user_rid
))
1412 /* oh, whoops. don't know what error message to return, here */
1413 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1416 if (r_u
.status
!= 0 && pol_open
)
1418 close_lsa_policy_hnd(&(r_u
.user_pol
));
1421 DEBUG(5,("samr_open_user: %d\n", __LINE__
));
1423 /* store the response in the SMB stream */
1424 if(!samr_io_r_open_user("", &r_u
, rdata
, 0))
1427 DEBUG(5,("samr_open_user: %d\n", __LINE__
));
1432 /*******************************************************************
1434 ********************************************************************/
1435 static BOOL
api_samr_open_user(pipes_struct
*p
)
1437 SAMR_Q_OPEN_USER q_u
;
1438 prs_struct
*data
= &p
->in_data
.data
;
1439 prs_struct
*rdata
= &p
->out_data
.rdata
;
1441 /* grab the samr unknown 22 */
1442 if(!samr_io_q_open_user("", &q_u
, data
, 0))
1445 /* construct reply. always indicate success */
1446 if(!samr_reply_open_user(&q_u
, rdata
, 0x0))
1453 /*************************************************************************
1455 *************************************************************************/
1456 static BOOL
get_user_info_10(SAM_USER_INFO_10
*id10
, uint32 user_rid
)
1458 struct smb_passwd
*smb_pass
;
1460 if (!pdb_rid_is_user(user_rid
))
1462 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1467 smb_pass
= getsmbpwrid(user_rid
);
1470 if (smb_pass
== NULL
)
1472 DEBUG(4,("User 0x%x not found\n", user_rid
));
1476 DEBUG(3,("User:[%s]\n", smb_pass
->smb_name
));
1478 init_sam_user_info10(id10
, smb_pass
->acct_ctrl
);
1483 /*************************************************************************
1485 *************************************************************************/
1486 static BOOL
get_user_info_21(SAM_USER_INFO_21
*id21
, uint32 user_rid
)
1489 struct sam_passwd
*sam_pass
;
1493 if (!pdb_rid_is_user(user_rid
))
1495 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1500 sam_pass
= getsam21pwrid(user_rid
);
1503 if (sam_pass
== NULL
)
1505 DEBUG(4,("User 0x%x not found\n", user_rid
));
1509 DEBUG(3,("User:[%s]\n", sam_pass
->smb_name
));
1511 dummy_time
.low
= 0xffffffff;
1512 dummy_time
.high
= 0x7fffffff;
1514 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1516 /* create a LOGON_HRS structure */
1517 hrs
.len
= sam_pass
->hours_len
;
1518 SMB_ASSERT_ARRAY(hrs
.hours
, hrs
.len
);
1519 for (i
= 0; i
< hrs
.len
; i
++)
1521 hrs
.hours
[i
] = sam_pass
->hours
[i
];
1524 init_sam_user_info21(id21
,
1526 &dummy_time
, /* logon_time */
1527 &dummy_time
, /* logoff_time */
1528 &dummy_time
, /* kickoff_time */
1529 &dummy_time
, /* pass_last_set_time */
1530 &dummy_time
, /* pass_can_change_time */
1531 &dummy_time
, /* pass_must_change_time */
1533 sam_pass
->smb_name
, /* user_name */
1534 sam_pass
->full_name
, /* full_name */
1535 sam_pass
->home_dir
, /* home_dir */
1536 sam_pass
->dir_drive
, /* dir_drive */
1537 sam_pass
->logon_script
, /* logon_script */
1538 sam_pass
->profile_path
, /* profile_path */
1539 sam_pass
->acct_desc
, /* description */
1540 sam_pass
->workstations
, /* workstations user can log in from */
1541 sam_pass
->unknown_str
, /* don't know, yet */
1542 sam_pass
->munged_dial
, /* dialin info. contains dialin path and tel no */
1544 sam_pass
->user_rid
, /* RID user_id */
1545 sam_pass
->group_rid
, /* RID group_id */
1546 sam_pass
->acct_ctrl
,
1548 sam_pass
->unknown_3
, /* unknown_3 */
1549 sam_pass
->logon_divs
, /* divisions per week */
1550 &hrs
, /* logon hours */
1551 sam_pass
->unknown_5
,
1552 sam_pass
->unknown_6
);
1557 /*******************************************************************
1558 samr_reply_query_userinfo
1559 ********************************************************************/
1560 static BOOL
samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO
*q_u
,
1563 SAMR_R_QUERY_USERINFO r_u
;
1565 SAM_USER_INFO_11 id11
;
1567 SAM_USER_INFO_10 id10
;
1568 SAM_USER_INFO_21 id21
;
1571 uint32 status
= 0x0;
1574 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__
));
1576 /* search for the handle */
1577 if (status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
1579 status
= NT_STATUS_INVALID_HANDLE
;
1582 /* find the user's rid */
1583 if (status
== 0x0 && (rid
= get_lsa_policy_samr_rid(&(q_u
->pol
))) == 0xffffffff)
1585 status
= NT_STATUS_OBJECT_TYPE_MISMATCH
;
1588 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid
));
1590 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1593 switch (q_u
->switch_value
)
1597 info
= (void*)&id10
;
1598 status
= get_user_info_10(&id10
, rid
) ? 0 : NT_STATUS_NO_SUCH_USER
;
1602 /* whoops - got this wrong. i think. or don't understand what's happening. */
1606 info
= (void*)&id11
;
1608 expire
.low
= 0xffffffff;
1609 expire
.high
= 0x7fffffff;
1611 make_sam_user_info11(&id11
, &expire
, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1618 info
= (void*)&id21
;
1619 status
= get_user_info_21(&id21
, rid
) ? 0 : NT_STATUS_NO_SUCH_USER
;
1625 status
= NT_STATUS_INVALID_INFO_CLASS
;
1632 init_samr_r_query_userinfo(&r_u
, q_u
->switch_value
, info
, status
);
1634 /* store the response in the SMB stream */
1635 if(!samr_io_r_query_userinfo("", &r_u
, rdata
, 0))
1638 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__
));
1643 /*******************************************************************
1644 api_samr_query_userinfo
1645 ********************************************************************/
1646 static BOOL
api_samr_query_userinfo(pipes_struct
*p
)
1648 SAMR_Q_QUERY_USERINFO q_u
;
1649 prs_struct
*data
= &p
->in_data
.data
;
1650 prs_struct
*rdata
= &p
->out_data
.rdata
;
1652 /* grab the samr unknown 24 */
1653 if(!samr_io_q_query_userinfo("", &q_u
, data
, 0))
1656 /* construct reply. always indicate success */
1657 if(!samr_reply_query_userinfo(&q_u
, rdata
))
1664 /*******************************************************************
1665 samr_reply_query_usergroups
1666 ********************************************************************/
1667 static BOOL
samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS
*q_u
,
1670 SAMR_R_QUERY_USERGROUPS r_u
;
1671 uint32 status
= 0x0;
1673 struct sam_passwd
*sam_pass
;
1674 DOM_GID
*gids
= NULL
;
1678 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__
));
1680 /* find the policy handle. open a policy on it. */
1681 if (status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->pol
)) == -1))
1683 status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
1686 /* find the user's rid */
1687 if (status
== 0x0 && (rid
= get_lsa_policy_samr_rid(&(q_u
->pol
))) == 0xffffffff)
1689 status
= NT_STATUS_OBJECT_TYPE_MISMATCH
;
1695 sam_pass
= getsam21pwrid(rid
);
1698 if (sam_pass
== NULL
)
1700 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1707 get_domain_user_groups(groups
, sam_pass
->smb_name
);
1709 num_groups
= make_dom_gids(groups
, &gids
);
1712 /* construct the response. lkclXXXX: gids are not copied! */
1713 init_samr_r_query_usergroups(&r_u
, num_groups
, gids
, status
);
1715 /* store the response in the SMB stream */
1716 if(!samr_io_r_query_usergroups("", &r_u
, rdata
, 0)) {
1725 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__
));
1730 /*******************************************************************
1731 api_samr_query_usergroups
1732 ********************************************************************/
1733 static BOOL
api_samr_query_usergroups(pipes_struct
*p
)
1735 SAMR_Q_QUERY_USERGROUPS q_u
;
1736 prs_struct
*data
= &p
->in_data
.data
;
1737 prs_struct
*rdata
= &p
->out_data
.rdata
;
1739 /* grab the samr unknown 32 */
1740 if(!samr_io_q_query_usergroups("", &q_u
, data
, 0))
1743 /* construct reply. */
1744 if(!samr_reply_query_usergroups(&q_u
, rdata
))
1751 /*******************************************************************
1752 samr_reply_query_dom_info
1753 ********************************************************************/
1754 static BOOL
samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, prs_struct
*rdata
)
1756 SAMR_R_QUERY_DOMAIN_INFO r_u
;
1758 uint16 switch_value
= 0x0;
1759 uint32 status
= 0x0;
1766 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__
));
1768 /* find the policy handle. open a policy on it. */
1769 if (r_u
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->domain_pol
)) == -1))
1771 r_u
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
1772 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1777 switch (q_u
->switch_value
)
1782 init_unk_info2(&ctr
.info
.inf2
, global_myworkgroup
, global_myname
);
1788 status
= 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS
;
1794 init_samr_r_query_dom_info(&r_u
, switch_value
, &ctr
, status
);
1796 /* store the response in the SMB stream */
1797 if(!samr_io_r_query_dom_info("", &r_u
, rdata
, 0))
1800 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__
));
1805 /*******************************************************************
1806 api_samr_query_dom_info
1807 ********************************************************************/
1808 static BOOL
api_samr_query_dom_info(pipes_struct
*p
)
1810 SAMR_Q_QUERY_DOMAIN_INFO q_e
;
1811 prs_struct
*data
= &p
->in_data
.data
;
1812 prs_struct
*rdata
= &p
->out_data
.rdata
;
1814 /* grab the samr unknown 8 command */
1815 if(!samr_io_q_query_dom_info("", &q_e
, data
, 0))
1818 /* construct reply. */
1819 if(!samr_reply_query_dom_info(&q_e
, rdata
))
1825 /*******************************************************************
1826 samr_reply_unknown_32
1827 ********************************************************************/
1828 static BOOL
samr_reply_unknown_32(SAMR_Q_UNKNOWN_32
*q_u
,
1833 SAMR_R_UNKNOWN_32 r_u
;
1835 /* set up the SAMR unknown_32 response */
1836 memset((char *)r_u
.pol
.data
, '\0', POL_HND_SIZE
);
1839 for (i
= 4; i
< POL_HND_SIZE
; i
++)
1841 r_u
.pol
.data
[i
] = i
+1;
1845 init_dom_rid4(&(r_u
.rid4
), 0x0030, 0, 0);
1846 r_u
.status
= status
;
1848 DEBUG(5,("samr_unknown_32: %d\n", __LINE__
));
1850 /* store the response in the SMB stream */
1851 if(!samr_io_r_unknown_32("", &r_u
, rdata
, 0))
1854 DEBUG(5,("samr_unknown_32: %d\n", __LINE__
));
1859 /*******************************************************************
1861 ********************************************************************/
1862 static BOOL
api_samr_unknown_32(pipes_struct
*p
)
1865 struct sam_passwd
*sam_pass
;
1867 prs_struct
*data
= &p
->in_data
.data
;
1868 prs_struct
*rdata
= &p
->out_data
.rdata
;
1870 SAMR_Q_UNKNOWN_32 q_u
;
1872 /* grab the samr unknown 32 */
1873 samr_io_q_unknown_32("", &q_u
, data
, 0);
1875 /* find the machine account: tell the caller if it exists.
1876 lkclXXXX i have *no* idea if this is a problem or not
1877 or even if you are supposed to construct a different
1878 reply if the account already exists...
1881 fstrcpy(mach_acct
, dos_unistrn2(q_u
.uni_mach_acct
.buffer
,
1882 q_u
.uni_mach_acct
.uni_str_len
));
1885 sam_pass
= getsam21pwnam(mach_acct
);
1888 if (sam_pass
!= NULL
)
1890 /* machine account exists: say so */
1891 status
= 0xC0000000 | NT_STATUS_USER_EXISTS
;
1895 /* this could cause trouble... */
1896 DEBUG(0,("trouble!\n"));
1900 /* construct reply. */
1901 if(!samr_reply_unknown_32(&q_u
, rdata
, status
))
1908 /*******************************************************************
1909 samr_reply_connect_anon
1910 ********************************************************************/
1911 static BOOL
samr_reply_connect_anon(SAMR_Q_CONNECT_ANON
*q_u
, prs_struct
*rdata
)
1913 SAMR_R_CONNECT_ANON r_u
;
1914 BOOL pol_open
= False
;
1916 /* set up the SAMR connect_anon response */
1919 /* get a (unique) handle. open a policy on it. */
1920 if (r_u
.status
== 0x0 && !(pol_open
= open_lsa_policy_hnd(&(r_u
.connect_pol
))))
1922 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1925 /* associate the domain SID with the (unique) handle. */
1926 if (r_u
.status
== 0x0 && !set_lsa_policy_samr_pol_status(&(r_u
.connect_pol
), q_u
->unknown_0
))
1928 /* oh, whoops. don't know what error message to return, here */
1929 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1932 if (r_u
.status
!= 0 && pol_open
)
1934 close_lsa_policy_hnd(&(r_u
.connect_pol
));
1937 DEBUG(5,("samr_connect_anon: %d\n", __LINE__
));
1939 /* store the response in the SMB stream */
1940 if(!samr_io_r_connect_anon("", &r_u
, rdata
, 0))
1943 DEBUG(5,("samr_connect_anon: %d\n", __LINE__
));
1948 /*******************************************************************
1949 api_samr_connect_anon
1950 ********************************************************************/
1951 static BOOL
api_samr_connect_anon(pipes_struct
*p
)
1953 SAMR_Q_CONNECT_ANON q_u
;
1954 prs_struct
*data
= &p
->in_data
.data
;
1955 prs_struct
*rdata
= &p
->out_data
.rdata
;
1957 /* grab the samr open policy */
1958 if(!samr_io_q_connect_anon("", &q_u
, data
, 0))
1961 /* construct reply. always indicate success */
1962 if(!samr_reply_connect_anon(&q_u
, rdata
))
1968 /*******************************************************************
1970 ********************************************************************/
1971 static BOOL
samr_reply_connect(SAMR_Q_CONNECT
*q_u
, prs_struct
*rdata
)
1974 BOOL pol_open
= False
;
1976 /* set up the SAMR connect response */
1979 /* get a (unique) handle. open a policy on it. */
1980 if (r_u
.status
== 0x0 && !(pol_open
= open_lsa_policy_hnd(&(r_u
.connect_pol
))))
1982 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1985 /* associate the domain SID with the (unique) handle. */
1986 if (r_u
.status
== 0x0 && !set_lsa_policy_samr_pol_status(&(r_u
.connect_pol
), q_u
->unknown_0
))
1988 /* oh, whoops. don't know what error message to return, here */
1989 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1992 if (r_u
.status
!= 0 && pol_open
)
1994 close_lsa_policy_hnd(&(r_u
.connect_pol
));
1997 DEBUG(5,("samr_connect: %d\n", __LINE__
));
1999 /* store the response in the SMB stream */
2000 if(!samr_io_r_connect("", &r_u
, rdata
, 0))
2003 DEBUG(5,("samr_connect: %d\n", __LINE__
));
2008 /*******************************************************************
2010 ********************************************************************/
2011 static BOOL
api_samr_connect(pipes_struct
*p
)
2014 prs_struct
*data
= &p
->in_data
.data
;
2015 prs_struct
*rdata
= &p
->out_data
.rdata
;
2017 /* grab the samr open policy */
2018 if(!samr_io_q_connect("", &q_u
, data
, 0))
2021 /* construct reply. always indicate success */
2022 if(!samr_reply_connect(&q_u
, rdata
))
2028 /**********************************************************************
2029 api_reply_lookup_domain
2030 **********************************************************************/
2031 static BOOL
samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN
* q_u
, prs_struct
* rdata
)
2033 SAMR_R_LOOKUP_DOMAIN r_u
;
2036 if (r_u
.status
== 0x0 && (find_lsa_policy_by_hnd(&(q_u
->connect_pol
)) == -1))
2038 r_u
.status
= 0xC0000000 | NT_STATUS_INVALID_HANDLE
;
2039 DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
2042 /* assume the domain name sent is our global_myname and
2043 send global_sam_sid */
2044 init_samr_r_lookup_domain(&r_u
, &global_sam_sid
, r_u
.status
);
2046 if(!samr_io_r_lookup_domain("", &r_u
, rdata
, 0))
2049 DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__
));
2054 /**********************************************************************
2055 api_samr_lookup_domain
2056 **********************************************************************/
2057 static BOOL
api_samr_lookup_domain(pipes_struct
*p
)
2059 SAMR_Q_LOOKUP_DOMAIN q_u
;
2060 prs_struct
*data
= &p
->in_data
.data
;
2061 prs_struct
*rdata
= &p
->out_data
.rdata
;
2063 if(!samr_io_q_lookup_domain("", &q_u
, data
, 0))
2066 if(!samr_reply_lookup_domain(&q_u
, rdata
))
2072 /**********************************************************************
2073 samr_reply_enum_domains
2074 **********************************************************************/
2075 static BOOL
samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS
* q_u
, prs_struct
* rdata
)
2077 SAMR_R_ENUM_DOMAINS r_u
;
2080 fstrcpy(dom
[0],global_myname
);
2081 fstrcpy(dom
[1],"Builtin");
2084 init_samr_r_enum_domains(&r_u
, q_u
->start_idx
, dom
, 2);
2085 if(!samr_io_r_enum_domains("", &r_u
, rdata
, 0)) {
2087 free(r_u
.uni_dom_name
);
2092 free(r_u
.uni_dom_name
);
2097 /**********************************************************************
2098 api_samr_enum_domains
2099 **********************************************************************/
2100 static BOOL
api_samr_enum_domains(pipes_struct
*p
)
2102 SAMR_Q_ENUM_DOMAINS q_u
;
2103 prs_struct
*data
= &p
->in_data
.data
;
2104 prs_struct
*rdata
= &p
->out_data
.rdata
;
2106 if(!samr_io_q_enum_domains("", &q_u
, data
, 0))
2109 if(!samr_reply_enum_domains(&q_u
, rdata
))
2115 /*******************************************************************
2116 samr_reply_open_alias
2117 ********************************************************************/
2118 static BOOL
samr_reply_open_alias(SAMR_Q_OPEN_ALIAS
*q_u
, prs_struct
*rdata
)
2120 SAMR_R_OPEN_ALIAS r_u
;
2121 BOOL pol_open
= False
;
2123 /* set up the SAMR open_alias response */
2126 /* get a (unique) handle. open a policy on it. */
2127 if (r_u
.status
== 0x0 && !(pol_open
= open_lsa_policy_hnd(&(r_u
.pol
))))
2129 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2132 /* associate a RID with the (unique) handle. */
2133 if (r_u
.status
== 0x0 && !set_lsa_policy_samr_rid(&(r_u
.pol
), q_u
->rid_alias
))
2135 /* oh, whoops. don't know what error message to return, here */
2136 r_u
.status
= 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2139 if (r_u
.status
!= 0 && pol_open
)
2141 close_lsa_policy_hnd(&(r_u
.pol
));
2144 DEBUG(5,("samr_open_alias: %d\n", __LINE__
));
2146 /* store the response in the SMB stream */
2147 if(!samr_io_r_open_alias("", &r_u
, rdata
, 0))
2150 DEBUG(5,("samr_open_alias: %d\n", __LINE__
));
2155 /*******************************************************************
2157 ********************************************************************/
2158 static BOOL
api_samr_open_alias(pipes_struct
*p
)
2160 SAMR_Q_OPEN_ALIAS q_u
;
2161 prs_struct
*data
= &p
->in_data
.data
;
2162 prs_struct
*rdata
= &p
->out_data
.rdata
;
2164 /* grab the samr open policy */
2165 if(!samr_io_q_open_alias("", &q_u
, data
, 0))
2168 /* construct reply. always indicate success */
2169 if(!samr_reply_open_alias(&q_u
, rdata
))
2175 /*******************************************************************
2176 array of \PIPE\samr operations
2177 ********************************************************************/
2178 static struct api_struct api_samr_cmds
[] =
2180 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND
, api_samr_close_hnd
},
2181 { "SAMR_CONNECT" , SAMR_CONNECT
, api_samr_connect
},
2182 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON
, api_samr_connect_anon
},
2183 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS
, api_samr_enum_dom_users
},
2184 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS
, api_samr_enum_dom_groups
},
2185 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES
, api_samr_enum_dom_aliases
},
2186 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS
, api_samr_lookup_ids
},
2187 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES
, api_samr_lookup_names
},
2188 { "SAMR_OPEN_USER" , SAMR_OPEN_USER
, api_samr_open_user
},
2189 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO
, api_samr_query_userinfo
},
2190 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO
, api_samr_query_dom_info
},
2191 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS
, api_samr_query_usergroups
},
2192 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO
, api_samr_query_dispinfo
},
2193 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO
, api_samr_query_aliasinfo
},
2194 { "SAMR_0x32" , 0x32 , api_samr_unknown_32
},
2195 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12
, api_samr_unknown_12
},
2196 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38
, api_samr_unknown_38
},
2197 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER
, api_samr_chgpasswd_user
},
2198 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS
, api_samr_open_alias
},
2199 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN
, api_samr_open_domain
},
2200 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3
, api_samr_unknown_3
},
2201 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C
, api_samr_unknown_2c
},
2202 { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN
, api_samr_lookup_domain
},
2203 { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS
, api_samr_enum_domains
},
2207 /*******************************************************************
2208 receives a samr pipe and responds.
2209 ********************************************************************/
2210 BOOL
api_samr_rpc(pipes_struct
*p
)
2212 return api_rpcTNP(p
, "api_samr_rpc", api_samr_cmds
);