4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Security Accounts Manager RPC (SAMR) server-side interface.
29 *
30 * The SAM is a hierarchical database:
31 * - If you want to talk to the SAM you need a SAM handle.
32 * - If you want to work with a domain, use the SAM handle.
33 * to obtain a domain handle.
34 * - Use domain handles to obtain user handles etc.
35 */
36
37 #include <strings.h>
38 #include <unistd.h>
39 #include <netdb.h>
40 #include <assert.h>
41 #include <grp.h>
42 #include <smbsrv/libsmb.h>
43 #include <smbsrv/libmlrpc.h>
44 #include <smbsrv/libmlsvc.h>
45 #include <smbsrv/smbinfo.h>
46 #include <smbsrv/nmpipes.h>
47 #include <smbsrv/ndl/samrpc.ndl>
48 #include <samlib.h>
49
50 /*
51 * The keys associated with the various handles dispensed by the SAMR
52 * server. These keys can be used to validate client activity.
53 * These values are never passed over the wire so security shouldn't
54 * be an issue.
55 */
56 typedef enum {
57 SAMR_KEY_NULL = 0,
58 SAMR_KEY_CONNECT,
59 SAMR_KEY_DOMAIN,
60 SAMR_KEY_USER,
61 SAMR_KEY_GROUP,
62 SAMR_KEY_ALIAS
63 } samr_key_t;
85 *
86 * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
87 */
88 typedef enum {
89 DomainDisplayUser = 1,
90 DomainDisplayMachine,
91 DomainDispalyGroup,
92 DomainDisplayOemUser,
93 DomainDisplayOemGroup
94 } samr_displvl_t;
95
96 #define SAMR_VALID_DISPLEVEL(lvl) \
97 (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
98
99 #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
100
101 static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
102 DWORD);
103 static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
104 static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
105 static int samr_call_stub(ndr_xa_t *mxa);
106 static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
107 ndr_xa_t *);
108
109 static ndr_stub_table_t samr_stub_table[];
110
111 static ndr_service_t samr_service = {
112 "SAMR", /* name */
113 "Security Accounts Manager", /* desc */
114 "\\samr", /* endpoint */
115 PIPE_LSASS, /* sec_addr_port */
116 "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */
117 NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
118 0, /* no bind_instance_size */
119 NULL, /* no bind_req() */
120 NULL, /* no unbind_and_close() */
121 samr_call_stub, /* call_stub() */
122 &TYPEINFO(samr_interface), /* interface ti */
123 samr_stub_table /* stub_table */
124 };
197 */
198 static ndr_handle_t *
199 samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
200 {
201 ndr_handle_t *hd;
202 samr_keydata_t *data;
203
204 if ((hd = ndr_hdlookup(mxa, id)) == NULL)
205 return (NULL);
206
207 if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
208 return (NULL);
209
210 if (data->kd_key != key)
211 return (NULL);
212
213 return (hd);
214 }
215
216 /*
217 * samr_s_Connect
218 *
219 * This is a request to connect to the local SAM database. We don't
220 * support any form of update request and our database doesn't
221 * contain any private information, so there is little point in
222 * doing any access access checking here.
223 *
224 * Return a handle for use with subsequent SAM requests.
225 */
226 static int
227 samr_s_Connect(void *arg, ndr_xa_t *mxa)
228 {
229 struct samr_Connect *param = arg;
230 ndr_hdid_t *id;
231
232 id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
233 if (id) {
234 bcopy(id, ¶m->handle, sizeof (samr_handle_t));
235 param->status = 0;
236 } else {
244 /*
245 * samr_s_CloseHandle
246 *
247 * Close the SAM interface specified by the handle.
248 * Free the handle and zero out the result handle for the client.
249 */
250 static int
251 samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
252 {
253 struct samr_CloseHandle *param = arg;
254 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
255
256 samr_hdfree(mxa, id);
257
258 bzero(¶m->result_handle, sizeof (samr_handle_t));
259 param->status = 0;
260 return (NDR_DRC_OK);
261 }
262
263 /*
264 * samr_s_LookupDomain
265 *
266 * This is a request to map a domain name to a domain SID. We can map
267 * the primary domain name, our local domain name (hostname) and the
268 * builtin domain names to the appropriate SID. Anything else will be
269 * rejected.
270 */
271 static int
272 samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
273 {
274 struct samr_LookupDomain *param = arg;
275 char *domain_name;
276 smb_domain_t di;
277
278 if ((domain_name = (char *)param->domain_name.str) == NULL) {
279 bzero(param, sizeof (struct samr_LookupDomain));
280 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
281 return (NDR_DRC_OK);
282 }
283
672 {
673 struct samr_DeleteUser *param = arg;
674
675 bzero(param, sizeof (struct samr_DeleteUser));
676 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
677 return (NDR_DRC_OK);
678 }
679
680 /*
681 * samr_s_QueryUserInfo
682 *
683 * Returns:
684 * NT_STATUS_SUCCESS
685 * NT_STATUS_ACCESS_DENIED
686 * NT_STATUS_INVALID_INFO_CLASS
687 */
688 /*ARGSUSED*/
689 static int
690 samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
691 {
692 static uint16_t owf_buf[8];
693 static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ];
694 struct samr_QueryUserInfo *param = arg;
695 struct samr_QueryUserInfo21 *all_info;
696 ndr_hdid_t *id;
697 ndr_handle_t *hd;
698 samr_keydata_t *data;
699 smb_domain_t di;
700 smb_account_t account;
701 smb_sid_t *sid;
702 uint32_t status;
703
704 id = (ndr_hdid_t *)¶m->user_handle;
705 if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
706 status = NT_STATUS_INVALID_HANDLE;
707 goto QueryUserInfoError;
708 }
709
710 data = (samr_keydata_t *)hd->nh_data;
711
712 if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
713 status = NT_STATUS_ACCESS_DENIED;
715 }
716
717 if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
718 status = NT_STATUS_ACCESS_DENIED;
719 goto QueryUserInfoError;
720 }
721
722 if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
723 status = NT_STATUS_ACCESS_DENIED;
724 goto QueryUserInfoError;
725 }
726
727 if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
728 status = NT_STATUS_ACCESS_DENIED;
729 goto QueryUserInfoError;
730 }
731
732 all_info = ¶m->ru.info21;
733 bzero(all_info, sizeof (struct samr_QueryUserInfo21));
734
735 all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID;
736
737 (void) NDR_MSTRING(mxa, account.a_name,
738 (ndr_mstring_t *)&all_info->UserName);
739 all_info->UserId = data->kd_rid;
740
741 all_info->LmOwfPassword.length = 16;
742 all_info->LmOwfPassword.maxlen = 16;
743 all_info->LmOwfPassword.buf = owf_buf;
744 all_info->NtOwfPassword.length = 16;
745 all_info->NtOwfPassword.maxlen = 16;
746 all_info->NtOwfPassword.buf = owf_buf;
747 all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK;
748 all_info->LogonHours.hours = hour_buf;
749
750 param->address = 1;
751 param->switch_index = SAMR_QUERY_USER_ALL_INFO;
752 param->status = NT_STATUS_SUCCESS;
753 smb_account_free(&account);
754 smb_sid_free(sid);
755 return (NDR_DRC_OK);
756
757 QueryUserInfoError:
758 smb_sid_free(sid);
759 bzero(param, sizeof (struct samr_QueryUserInfo));
760 param->status = NT_SC_ERROR(status);
761 return (NDR_DRC_OK);
762 }
763
764 /*
765 * samr_s_QueryUserGroups
766 *
767 * Request the list of groups of which a user is a member.
768 * The user is identified from the handle, which contains an
769 * rid in the discriminator field. Note that this is a local user.
1834
1835 /*
1836 * samr_s_Connect5
1837 *
1838 * This is the connect5 form of the connect request used by Windows XP.
1839 * Returns an RPC fault for now.
1840 */
1841 /*ARGSUSED*/
1842 static int
1843 samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1844 {
1845 struct samr_Connect5 *param = arg;
1846
1847 bzero(param, sizeof (struct samr_Connect5));
1848 return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1849 }
1850
1851 static ndr_stub_table_t samr_stub_table[] = {
1852 { samr_s_Connect, SAMR_OPNUM_Connect },
1853 { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
1854 { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
1855 { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
1856 { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
1857 { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
1858 { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
1859 { samr_s_LookupNames, SAMR_OPNUM_LookupNames },
1860 { samr_s_OpenUser, SAMR_OPNUM_OpenUser },
1861 { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
1862 { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo },
1863 { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups },
1864 { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup },
1865 { samr_s_Connect2, SAMR_OPNUM_Connect2 },
1866 { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo },
1867 { samr_s_CreateUser, SAMR_OPNUM_CreateUser },
1868 { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 },
1869 { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo },
1870 { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo },
1871 { samr_s_Connect4, SAMR_OPNUM_Connect4 },
1872 { samr_s_Connect5, SAMR_OPNUM_Connect5 },
1873 { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo },
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Security Accounts Manager RPC (SAMR) server-side interface.
29 *
30 * The SAM is a hierarchical database:
31 * - If you want to talk to the SAM you need a SAM handle.
32 * - If you want to work with a domain, use the SAM handle.
33 * to obtain a domain handle.
34 * - Use domain handles to obtain user handles etc.
35 */
36
37 #include <strings.h>
38 #include <unistd.h>
39 #include <netdb.h>
40 #include <assert.h>
41 #include <grp.h>
42 #include <libmlrpc/libmlrpc.h>
43 #include <smbsrv/libsmb.h>
44 #include <smbsrv/libmlsvc.h>
45 #include <smbsrv/smbinfo.h>
46 #include <smbsrv/nmpipes.h>
47 #include <smbsrv/ndl/samrpc.ndl>
48 #include <samlib.h>
49
50 /*
51 * The keys associated with the various handles dispensed by the SAMR
52 * server. These keys can be used to validate client activity.
53 * These values are never passed over the wire so security shouldn't
54 * be an issue.
55 */
56 typedef enum {
57 SAMR_KEY_NULL = 0,
58 SAMR_KEY_CONNECT,
59 SAMR_KEY_DOMAIN,
60 SAMR_KEY_USER,
61 SAMR_KEY_GROUP,
62 SAMR_KEY_ALIAS
63 } samr_key_t;
85 *
86 * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings
87 */
88 typedef enum {
89 DomainDisplayUser = 1,
90 DomainDisplayMachine,
91 DomainDispalyGroup,
92 DomainDisplayOemUser,
93 DomainDisplayOemGroup
94 } samr_displvl_t;
95
96 #define SAMR_VALID_DISPLEVEL(lvl) \
97 (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup))
98
99 #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
100
101 static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t,
102 DWORD);
103 static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
104 static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
105 static ndr_handle_t *samr_hdlookup_any(ndr_xa_t *, ndr_hdid_t *);
106 static int samr_call_stub(ndr_xa_t *mxa);
107 static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
108 ndr_xa_t *);
109
110 static ndr_stub_table_t samr_stub_table[];
111
112 static ndr_service_t samr_service = {
113 "SAMR", /* name */
114 "Security Accounts Manager", /* desc */
115 "\\samr", /* endpoint */
116 PIPE_LSASS, /* sec_addr_port */
117 "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */
118 NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
119 0, /* no bind_instance_size */
120 NULL, /* no bind_req() */
121 NULL, /* no unbind_and_close() */
122 samr_call_stub, /* call_stub() */
123 &TYPEINFO(samr_interface), /* interface ti */
124 samr_stub_table /* stub_table */
125 };
198 */
199 static ndr_handle_t *
200 samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
201 {
202 ndr_handle_t *hd;
203 samr_keydata_t *data;
204
205 if ((hd = ndr_hdlookup(mxa, id)) == NULL)
206 return (NULL);
207
208 if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
209 return (NULL);
210
211 if (data->kd_key != key)
212 return (NULL);
213
214 return (hd);
215 }
216
217 /*
218 * Handle lookup wrapper to validate the local context,
219 * but don't limit to one type.
220 */
221 static ndr_handle_t *
222 samr_hdlookup_any(ndr_xa_t *mxa, ndr_hdid_t *id)
223 {
224 ndr_handle_t *hd;
225
226 if ((hd = ndr_hdlookup(mxa, id)) == NULL)
227 return (NULL);
228
229 if (hd->nh_data == NULL)
230 return (NULL);
231
232 return (hd);
233 }
234
235 /*
236 * samr_s_Connect
237 *
238 * This is a request to connect to the local SAM database. We don't
239 * support any form of update request and our database doesn't
240 * contain any private information, so there is little point in
241 * doing any access access checking here.
242 *
243 * Return a handle for use with subsequent SAM requests.
244 */
245 static int
246 samr_s_Connect(void *arg, ndr_xa_t *mxa)
247 {
248 struct samr_Connect *param = arg;
249 ndr_hdid_t *id;
250
251 id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
252 if (id) {
253 bcopy(id, ¶m->handle, sizeof (samr_handle_t));
254 param->status = 0;
255 } else {
263 /*
264 * samr_s_CloseHandle
265 *
266 * Close the SAM interface specified by the handle.
267 * Free the handle and zero out the result handle for the client.
268 */
269 static int
270 samr_s_CloseHandle(void *arg, ndr_xa_t *mxa)
271 {
272 struct samr_CloseHandle *param = arg;
273 ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
274
275 samr_hdfree(mxa, id);
276
277 bzero(¶m->result_handle, sizeof (samr_handle_t));
278 param->status = 0;
279 return (NDR_DRC_OK);
280 }
281
282 /*
283 * samr_s_QuerySecObject
284 */
285 static int
286 samr_s_QuerySecObject(void *arg, ndr_xa_t *mxa)
287 {
288 struct samr_QuerySecObject *param = arg;
289 ndr_hdid_t *id;
290 uint32_t status;
291 struct samr_sec_desc *sd;
292
293 id = (ndr_hdid_t *)¶m->obj_handle;
294 if (samr_hdlookup_any(mxa, id) == NULL) {
295 status = NT_STATUS_INVALID_HANDLE;
296 goto QuerySecObjectError;
297 }
298
299 param->sd = NDR_MALLOC(mxa, sizeof (samr_sd_t));
300 if (param->sd == NULL) {
301 status = NT_STATUS_NO_MEMORY;
302 goto QuerySecObjectError;
303 }
304 param->sd->length = sizeof (struct samr_sec_desc);
305
306 sd = NDR_MALLOC(mxa, param->sd->length);
307 if (sd == NULL) {
308 status = NT_STATUS_NO_MEMORY;
309 goto QuerySecObjectError;
310 }
311 bzero(sd, param->sd->length);
312 sd->Revision = 1;
313 sd->Control = SE_SELF_RELATIVE;
314
315 param->sd->data = (void *)sd;
316 param->status = NT_STATUS_SUCCESS;
317 return (NDR_DRC_OK);
318
319 QuerySecObjectError:
320 bzero(param, sizeof (struct samr_QuerySecObject));
321 param->status = NT_SC_ERROR(status);
322 return (NDR_DRC_OK);
323 }
324
325 /*
326 * samr_s_LookupDomain
327 *
328 * This is a request to map a domain name to a domain SID. We can map
329 * the primary domain name, our local domain name (hostname) and the
330 * builtin domain names to the appropriate SID. Anything else will be
331 * rejected.
332 */
333 static int
334 samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
335 {
336 struct samr_LookupDomain *param = arg;
337 char *domain_name;
338 smb_domain_t di;
339
340 if ((domain_name = (char *)param->domain_name.str) == NULL) {
341 bzero(param, sizeof (struct samr_LookupDomain));
342 param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
343 return (NDR_DRC_OK);
344 }
345
734 {
735 struct samr_DeleteUser *param = arg;
736
737 bzero(param, sizeof (struct samr_DeleteUser));
738 param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
739 return (NDR_DRC_OK);
740 }
741
742 /*
743 * samr_s_QueryUserInfo
744 *
745 * Returns:
746 * NT_STATUS_SUCCESS
747 * NT_STATUS_ACCESS_DENIED
748 * NT_STATUS_INVALID_INFO_CLASS
749 */
750 /*ARGSUSED*/
751 static int
752 samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa)
753 {
754 struct samr_QueryUserInfo *param = arg;
755 struct samr_QueryUserInfo21 *all_info;
756 ndr_hdid_t *id;
757 ndr_handle_t *hd;
758 samr_keydata_t *data;
759 smb_domain_t di;
760 smb_account_t account;
761 smb_sid_t *sid;
762 uint32_t status;
763
764 id = (ndr_hdid_t *)¶m->user_handle;
765 if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
766 status = NT_STATUS_INVALID_HANDLE;
767 goto QueryUserInfoError;
768 }
769
770 data = (samr_keydata_t *)hd->nh_data;
771
772 if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) {
773 status = NT_STATUS_ACCESS_DENIED;
775 }
776
777 if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) {
778 status = NT_STATUS_ACCESS_DENIED;
779 goto QueryUserInfoError;
780 }
781
782 if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) {
783 status = NT_STATUS_ACCESS_DENIED;
784 goto QueryUserInfoError;
785 }
786
787 if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) {
788 status = NT_STATUS_ACCESS_DENIED;
789 goto QueryUserInfoError;
790 }
791
792 all_info = ¶m->ru.info21;
793 bzero(all_info, sizeof (struct samr_QueryUserInfo21));
794
795 all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID |
796 SAMR_USER_ALL_FULLNAME | SAMR_USER_ALL_USERACCOUNTCONTROL |
797 SAMR_USER_ALL_ADMINCOMMENT;
798
799 (void) NDR_MSTRING(mxa, account.a_name,
800 (ndr_mstring_t *)&all_info->UserName);
801 (void) NDR_MSTRING(mxa, account.a_name,
802 (ndr_mstring_t *)&all_info->FullName);
803 (void) NDR_MSTRING(mxa, "",
804 (ndr_mstring_t *)&all_info->AdminComment);
805
806 all_info->UserId = data->kd_rid;
807 all_info->UserAccountControl = SAMR_AF_NORMAL_ACCOUNT |
808 SAMR_AF_DONT_EXPIRE_PASSWD;
809 if ((account.a_flags & SMB_PWF_DISABLE) != 0)
810 all_info->UserAccountControl |= SAMR_AF_ACCOUNTDISABLE;
811
812 param->address = 1;
813 param->switch_index = SAMR_QUERY_USER_ALL_INFO;
814 param->status = NT_STATUS_SUCCESS;
815 smb_account_free(&account);
816 smb_sid_free(sid);
817 return (NDR_DRC_OK);
818
819 QueryUserInfoError:
820 smb_sid_free(sid);
821 bzero(param, sizeof (struct samr_QueryUserInfo));
822 param->status = NT_SC_ERROR(status);
823 return (NDR_DRC_OK);
824 }
825
826 /*
827 * samr_s_QueryUserGroups
828 *
829 * Request the list of groups of which a user is a member.
830 * The user is identified from the handle, which contains an
831 * rid in the discriminator field. Note that this is a local user.
1896
1897 /*
1898 * samr_s_Connect5
1899 *
1900 * This is the connect5 form of the connect request used by Windows XP.
1901 * Returns an RPC fault for now.
1902 */
1903 /*ARGSUSED*/
1904 static int
1905 samr_s_Connect5(void *arg, ndr_xa_t *mxa)
1906 {
1907 struct samr_Connect5 *param = arg;
1908
1909 bzero(param, sizeof (struct samr_Connect5));
1910 return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
1911 }
1912
1913 static ndr_stub_table_t samr_stub_table[] = {
1914 { samr_s_Connect, SAMR_OPNUM_Connect },
1915 { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle },
1916 { samr_s_QuerySecObject, SAMR_OPNUM_QuerySecObject },
1917 { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain },
1918 { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
1919 { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
1920 { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
1921 { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
1922 { samr_s_LookupNames, SAMR_OPNUM_LookupNames },
1923 { samr_s_OpenUser, SAMR_OPNUM_OpenUser },
1924 { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
1925 { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo },
1926 { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups },
1927 { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup },
1928 { samr_s_Connect2, SAMR_OPNUM_Connect2 },
1929 { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo },
1930 { samr_s_CreateUser, SAMR_OPNUM_CreateUser },
1931 { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 },
1932 { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo },
1933 { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo },
1934 { samr_s_Connect4, SAMR_OPNUM_Connect4 },
1935 { samr_s_Connect5, SAMR_OPNUM_Connect5 },
1936 { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo },
|