2 Unix SMB/Netbios implementation.
4 NT Domain Authentication SMB / MSRPC client
5 Copyright (C) Andrew Tridgell 1994-1997
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 extern int DEBUGLEVEL;
36 /****************************************************************************
37 do a SAMR query user groups
38 ****************************************************************************/
39 BOOL get_samr_query_usergroups(struct cli_state *cli, int t_idx, uint16 fnum,
40 POLICY_HND *pol_open_domain, uint32 user_rid,
41 uint32 *num_groups, DOM_GID *gid)
43 POLICY_HND pol_open_user;
44 if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
46 /* send open domain (on user sid) */
47 if (!do_samr_open_user(cli, t_idx, fnum,
55 /* send user groups query */
56 if (!do_samr_query_usergroups(cli, t_idx, fnum,
60 DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
63 return do_samr_close(cli, t_idx, fnum, &pol_open_user);
66 /****************************************************************************
67 do a SAMR query user info
68 ****************************************************************************/
69 BOOL get_samr_query_userinfo(struct cli_state *cli, int t_idx, uint16 fnum,
70 POLICY_HND *pol_open_domain,
72 uint32 user_rid, SAM_USER_INFO_21 *usr)
74 POLICY_HND pol_open_user;
75 if (pol_open_domain == NULL || usr == NULL) return False;
77 bzero(usr, sizeof(*usr));
79 /* send open domain (on user sid) */
80 if (!do_samr_open_user(cli, t_idx, fnum,
88 /* send user info query */
89 if (!do_samr_query_userinfo(cli, t_idx, fnum,
91 info_level, (void*)usr))
93 DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
97 return do_samr_close(cli, t_idx, fnum, &pol_open_user);
100 /****************************************************************************
101 do a SAMR unknown 0x8 command
102 ****************************************************************************/
103 BOOL do_samr_unknown_8(struct cli_state *cli, int t_idx, uint16 fnum,
104 POLICY_HND *domain_pol, uint16 switch_value)
109 SAMR_Q_UNKNOWN_8 q_e;
110 BOOL valid_un8 = False;
112 /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
114 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
115 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
117 DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
119 if (domain_pol == NULL || fnum == 0xffff) return False;
121 /* store the parameters */
122 make_samr_q_unknown_8(&q_e, domain_pol, switch_value);
124 /* turn parameters into data stream */
125 samr_io_q_unknown_8("", &q_e, &data, 0);
127 /* send the data on \PIPE\ */
128 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_UNKNOWN_8, &data, &rdata))
132 SAMR_R_UNKNOWN_8 r_e;
135 samr_io_r_unknown_8("", &r_e, &rdata, 0);
137 p = rdata.offset != 0;
138 if (p && r_e.status != 0)
140 /* report error code */
141 DEBUG(0,("SAMR_R_UNKNOWN_8: %s\n", get_nt_error_msg(r_e.status)));
152 prs_mem_free(&data );
153 prs_mem_free(&rdata );
158 /****************************************************************************
159 do a SAMR enumerate users
160 ****************************************************************************/
161 BOOL do_samr_enum_dom_users(struct cli_state *cli, int t_idx, uint16 fnum,
162 POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
163 uint16 acb_mask, uint16 unk_1, uint32 size,
164 struct acct_info sam[MAX_SAM_ENTRIES],
170 SAMR_Q_ENUM_DOM_USERS q_e;
171 BOOL valid_pol = False;
173 /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
175 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
176 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
178 DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
180 if (pol == NULL || sam == NULL || num_sam_users == NULL || fnum == 0xffff) return False;
182 /* store the parameters */
183 make_samr_q_enum_dom_users(&q_e, pol,
185 acb_mask, unk_1, size);
187 /* turn parameters into data stream */
188 samr_io_q_enum_dom_users("", &q_e, &data, 0);
190 /* send the data on \PIPE\ */
191 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_ENUM_DOM_USERS, &data, &rdata))
193 SAMR_R_ENUM_DOM_USERS r_e;
196 samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
198 p = rdata.offset != 0;
199 if (p && r_e.status != 0)
201 /* report error code */
202 DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
211 *num_sam_users = r_e.num_entries2;
212 if (*num_sam_users > MAX_SAM_ENTRIES)
214 *num_sam_users = MAX_SAM_ENTRIES;
215 DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
218 for (i = 0; i < *num_sam_users; i++)
220 sam[i].smb_userid = r_e.sam[i].rid;
221 if (r_e.sam[i].hdr_name.buffer)
223 char *acct_name = unistrn2(r_e.uni_acct_name[name_idx].buffer,
224 r_e.uni_acct_name[name_idx].uni_str_len);
225 fstrcpy(sam[i].acct_name, acct_name);
230 bzero(sam[i].acct_name, sizeof(sam[i].acct_name));
232 DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
233 i, sam[i].smb_userid, sam[i].acct_name));
239 prs_mem_free(&data );
240 prs_mem_free(&rdata );
245 /****************************************************************************
247 ****************************************************************************/
248 BOOL do_samr_connect(struct cli_state *cli, int t_idx, uint16 fnum,
249 char *srv_name, uint32 unknown_0,
250 POLICY_HND *connect_pol)
256 BOOL valid_pol = False;
258 /* create and send a MSRPC command with api SAMR_CONNECT */
260 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
261 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
263 DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
264 srv_name, unknown_0));
266 if (srv_name == NULL || connect_pol == NULL || fnum == 0xffff) return False;
268 /* store the parameters */
269 make_samr_q_connect(&q_o, srv_name, unknown_0);
271 /* turn parameters into data stream */
272 samr_io_q_connect("", &q_o, &data, 0);
274 /* send the data on \PIPE\ */
275 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_CONNECT, &data, &rdata))
280 samr_io_r_connect("", &r_o, &rdata, 0);
281 p = rdata.offset != 0;
283 if (p && r_o.status != 0)
285 /* report error code */
286 DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
292 memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
297 prs_mem_free(&data );
298 prs_mem_free(&rdata );
303 /****************************************************************************
305 ****************************************************************************/
306 BOOL do_samr_open_user(struct cli_state *cli, int t_idx, uint16 fnum,
307 POLICY_HND *pol, uint32 unk_0, uint32 rid,
308 POLICY_HND *user_pol)
313 SAMR_Q_OPEN_USER q_o;
314 BOOL valid_pol = False;
316 /* create and send a MSRPC command with api SAMR_OPEN_USER */
318 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
319 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
321 DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n",
324 if (pol == NULL || user_pol == NULL || fnum == 0xffff) return False;
326 /* store the parameters */
327 make_samr_q_open_user(&q_o, pol, unk_0, rid);
329 /* turn parameters into data stream */
330 samr_io_q_open_user("", &q_o, &data, 0);
332 /* send the data on \PIPE\ */
333 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_OPEN_USER, &data, &rdata))
335 SAMR_R_OPEN_USER r_o;
338 samr_io_r_open_user("", &r_o, &rdata, 0);
339 p = rdata.offset != 0;
341 if (p && r_o.status != 0)
343 /* report error code */
344 DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
350 memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
355 prs_mem_free(&data );
356 prs_mem_free(&rdata );
361 /****************************************************************************
362 do a SAMR Open Domain
363 ****************************************************************************/
364 BOOL do_samr_open_domain(struct cli_state *cli, int t_idx, uint16 fnum,
365 POLICY_HND *connect_pol, uint32 rid, char *sid,
366 POLICY_HND *domain_pol)
371 SAMR_Q_OPEN_DOMAIN q_o;
372 BOOL valid_pol = False;
374 /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
376 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
377 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
379 DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid, rid));
381 if (connect_pol == NULL || sid == NULL || domain_pol == NULL || fnum == 0xffff) return False;
383 /* store the parameters */
384 make_samr_q_open_domain(&q_o, connect_pol, rid, sid);
386 /* turn parameters into data stream */
387 samr_io_q_open_domain("", &q_o, &data, 0);
389 /* send the data on \PIPE\ */
390 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_OPEN_DOMAIN, &data, &rdata))
392 SAMR_R_OPEN_DOMAIN r_o;
395 samr_io_r_open_domain("", &r_o, &rdata, 0);
396 p = rdata.offset != 0;
398 if (p && r_o.status != 0)
400 /* report error code */
401 DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
407 memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
412 prs_mem_free(&data );
413 prs_mem_free(&rdata );
418 /****************************************************************************
419 do a SAMR Query Unknown 12
420 ****************************************************************************/
421 BOOL do_samr_query_unknown_12(struct cli_state *cli, int t_idx, uint16 fnum,
422 POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
424 fstring als_names [MAX_LOOKUP_SIDS],
425 uint32 num_als_users[MAX_LOOKUP_SIDS])
430 SAMR_Q_UNKNOWN_12 q_o;
431 BOOL valid_query = False;
433 /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
435 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
436 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
438 DEBUG(4,("SAMR Query Unknown 12.\n"));
440 if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
441 num_aliases == NULL || als_names == NULL || num_als_users == NULL ||
442 fnum == 0xffff) return False;
444 /* store the parameters */
445 make_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
447 /* turn parameters into data stream */
448 samr_io_q_unknown_12("", &q_o, &data, 0);
450 /* send the data on \PIPE\ */
451 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_UNKNOWN_12, &data, &rdata))
453 SAMR_R_UNKNOWN_12 r_o;
456 samr_io_r_unknown_12("", &r_o, &rdata, 0);
457 p = rdata.offset != 0;
459 if (p && r_o.status != 0)
461 /* report error code */
462 DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
468 if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
469 r_o.num_als_usrs1 == r_o.num_aliases1)
474 *num_aliases = r_o.num_aliases1;
476 for (i = 0; i < r_o.num_aliases1; i++)
478 fstrcpy(als_names[i], unistrn2(r_o.uni_als_name[i].buffer, r_o.uni_als_name[i].uni_str_len));
480 for (i = 0; i < r_o.num_als_usrs1; i++)
482 num_als_users[i] = r_o.num_als_usrs[i];
485 else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0)
497 prs_mem_free(&data );
498 prs_mem_free(&rdata );
503 /****************************************************************************
504 do a SAMR Query User Groups
505 ****************************************************************************/
506 BOOL do_samr_query_usergroups(struct cli_state *cli, int t_idx, uint16 fnum,
507 POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
512 SAMR_Q_QUERY_USERGROUPS q_o;
513 BOOL valid_query = False;
515 /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
517 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
518 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
520 DEBUG(4,("SAMR Query User Groups.\n"));
522 if (pol == NULL || gid == NULL || num_groups == 0|| fnum == 0xffff) return False;
524 /* store the parameters */
525 make_samr_q_query_usergroups(&q_o, pol);
527 /* turn parameters into data stream */
528 samr_io_q_query_usergroups("", &q_o, &data, 0);
530 /* send the data on \PIPE\ */
531 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_QUERY_USERGROUPS, &data, &rdata))
533 SAMR_R_QUERY_USERGROUPS r_o;
539 samr_io_r_query_usergroups("", &r_o, &rdata, 0);
540 p = rdata.offset != 0;
542 if (p && r_o.status != 0)
544 /* report error code */
545 DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
549 if (p && r_o.ptr_0 != 0)
552 *num_groups = r_o.num_entries;
557 prs_mem_free(&data );
558 prs_mem_free(&rdata );
563 /****************************************************************************
564 do a SAMR Query User Info
565 ****************************************************************************/
566 BOOL do_samr_query_userinfo(struct cli_state *cli, int t_idx, uint16 fnum,
567 POLICY_HND *pol, uint16 switch_value, void* usr)
572 SAMR_Q_QUERY_USERINFO q_o;
573 BOOL valid_query = False;
575 /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
577 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
578 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
580 DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value));
582 if (pol == NULL || usr == NULL || switch_value == 0|| fnum == 0xffff) return False;
584 /* store the parameters */
585 make_samr_q_query_userinfo(&q_o, pol, switch_value);
587 /* turn parameters into data stream */
588 samr_io_q_query_userinfo("", &q_o, &data, 0);
590 /* send the data on \PIPE\ */
591 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_QUERY_USERINFO, &data, &rdata))
593 SAMR_R_QUERY_USERINFO r_o;
599 samr_io_r_query_userinfo("", &r_o, &rdata, 0);
600 p = rdata.offset != 0;
602 if (p && r_o.status != 0)
604 /* report error code */
605 DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
609 if (p && r_o.switch_value != switch_value)
611 DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
615 if (p && r_o.ptr != 0)
621 prs_mem_free(&data );
622 prs_mem_free(&rdata );
627 /****************************************************************************
629 ****************************************************************************/
630 BOOL do_samr_close(struct cli_state *cli, int t_idx, uint16 fnum, POLICY_HND *hnd)
635 SAMR_Q_CLOSE_HND q_c;
636 BOOL valid_close = False;
638 prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
639 prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
641 if (hnd == NULL) return False;
643 /* create and send a MSRPC command with api SAMR_CLOSE_HND */
645 DEBUG(4,("SAMR Close\n"));
647 /* store the parameters */
648 make_samr_q_close_hnd(&q_c, hnd);
650 /* turn parameters into data stream */
651 samr_io_q_close_hnd("", &q_c, &data, 0);
653 /* send the data on \PIPE\ */
654 if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_CLOSE_HND, &data, &rdata))
656 SAMR_R_CLOSE_HND r_c;
659 samr_io_r_close_hnd("", &r_c, &rdata, 0);
660 p = rdata.offset != 0;
662 if (p && r_c.status != 0)
664 /* report error code */
665 DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
671 /* check that the returned policy handle is all zeros */
675 for (i = 0; i < sizeof(r_c.pol.data); i++)
677 if (r_c.pol.data[i] != 0)
685 DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
690 prs_mem_free(&data );
691 prs_mem_free(&rdata );