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 * Local Security Authority RPC (LSAR) client-side interface.
29 */
30
31 #include <sys/errno.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35
36 #include <smbsrv/libsmb.h>
37 #include <smbsrv/libmlsvc.h>
38 #include <smbsrv/smbinfo.h>
39 #include <smbsrv/ntaccess.h>
40 #include <smbsrv/ntlocale.h>
41 #include <smbsrv/string.h>
42 #include <lsalib.h>
43
44 /*
45 * The maximum number of bytes we are prepared to deal with in a
46 * response.
47 */
48 #define MLSVC_MAX_RESPONSE_LEN 1024
49
50 /*
51 * This structure is used when looking up names. We only lookup one
52 * name at a time but the structure will allow for more.
53 */
54 typedef struct lsa_names {
55 uint32_t n_entry;
56 mslsa_string_t name[8];
57 } lsa_names_t;
58
59 typedef DWORD (*lsar_nameop_t)(mlsvc_handle_t *, lsa_names_t *,
366 }
367 }
368
369 ndr_rpc_release(lsa_handle);
370 return (status);
371 }
372
373 /*
374 * Lookup a name and obtain the sid/rid.
375 * This is a wrapper for the various lookup sid RPCs.
376 */
377 uint32_t
378 lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
379 {
380 static lsar_nameop_t ops[] = {
381 lsar_lookup_names3,
382 lsar_lookup_names2,
383 lsar_lookup_names1
384 };
385
386 const srvsvc_server_info_t *svinfo;
387 lsa_names_t names;
388 char *p;
389 uint32_t length;
390 uint32_t status = NT_STATUS_INVALID_PARAMETER;
391 int n_op = (sizeof (ops) / sizeof (ops[0]));
392 int i;
393
394 if (lsa_handle == NULL || name == NULL || info == NULL)
395 return (NT_STATUS_INVALID_PARAMETER);
396
397 bzero(info, sizeof (smb_account_t));
398
399 svinfo = ndr_rpc_server_info(lsa_handle);
400 if (svinfo->sv_os == NATIVE_OS_WIN2000 &&
401 svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) {
402 /*
403 * Windows 2000 doesn't like an LSA lookup for
404 * DOMAIN\Administrator.
405 */
406 if ((p = strchr(name, '\\')) != 0) {
407 ++p;
408
409 if (strcasecmp(p, "administrator") == 0)
410 name = p;
411 }
412
413 }
414
415 length = smb_wcequiv_strlen(name);
416 names.name[0].length = length;
417 names.name[0].allosize = length;
418 names.name[0].str = (unsigned char *)name;
419 names.n_entry = 1;
420
421 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) {
422 for (i = 0; i < n_op; ++i) {
423 ndr_rpc_set_nonull(lsa_handle);
424 status = (*ops[i])(lsa_handle, &names, info);
425
426 if (status != NT_STATUS_INVALID_PARAMETER)
427 break;
428 }
429 } else {
430 ndr_rpc_set_nonull(lsa_handle);
431 status = lsar_lookup_names1(lsa_handle, &names, info);
432 }
433
434 if (status == NT_STATUS_SUCCESS) {
435 info->a_name = lsar_get_username(name);
436
437 if (!smb_account_validate(info)) {
438 smb_account_free(info);
439 status = NT_STATUS_NO_MEMORY;
440 } else {
441 smb_account_trace(info);
442 }
443 }
444
445 return (status);
446 }
447
448 /*
449 * The name may be in one of the following forms:
450 *
451 * domain\username
452 * domain/username
709
710 /*
711 * Lookup a sid and obtain the domain sid and account name.
712 * This is a wrapper for the various lookup sid RPCs.
713 */
714 uint32_t
715 lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
716 smb_account_t *account)
717 {
718 char sidbuf[SMB_SID_STRSZ];
719 uint32_t status;
720
721 if (lsa_handle == NULL || sid == NULL || account == NULL)
722 return (NT_STATUS_INVALID_PARAMETER);
723
724 bzero(account, sizeof (smb_account_t));
725 bzero(sidbuf, SMB_SID_STRSZ);
726 smb_sid_tostr(sid, sidbuf);
727 smb_tracef("%s", sidbuf);
728
729 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
730 status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid,
731 account);
732 else
733 status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
734 account);
735
736 if (status == NT_STATUS_SUCCESS) {
737 if (!smb_account_validate(account)) {
738 smb_account_free(account);
739 status = NT_STATUS_NO_MEMORY;
740 } else {
741 smb_account_trace(account);
742 }
743 }
744
745 return (status);
746 }
747
748 /*
749 * lsar_lookup_sids1
750 */
751 static uint32_t
752 lsar_lookup_sids1(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid,
1150 * a policy handle.
1151 */
1152 int
1153 lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name,
1154 struct ms_luid *luid)
1155 {
1156 struct mslsa_LookupPrivValue arg;
1157 int opnum;
1158 int rc;
1159 size_t length;
1160
1161 if (lsa_handle == NULL || name == NULL || luid == NULL)
1162 return (-1);
1163
1164 opnum = LSARPC_OPNUM_LookupPrivValue;
1165
1166 bzero(&arg, sizeof (struct mslsa_LookupPrivValue));
1167 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
1168
1169 length = smb_wcequiv_strlen(name);
1170 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
1171 length += sizeof (smb_wchar_t);
1172
1173 arg.name.length = length;
1174 arg.name.allosize = length;
1175 arg.name.str = (unsigned char *)name;
1176
1177 rc = ndr_rpc_call(lsa_handle, opnum, &arg);
1178 if (rc == 0) {
1179 if (arg.status != 0)
1180 rc = -1;
1181 else
1182 (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid));
1183 }
1184
1185 ndr_rpc_release(lsa_handle);
1186 return (rc);
1187 }
1188
1189 /*
1190 * lsar_lookup_priv_name
|
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 2018 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Local Security Authority RPC (LSAR) client-side interface.
29 */
30
31 #include <sys/errno.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35
36 #include <smbsrv/libsmb.h>
37 #include <smbsrv/libmlsvc.h>
38 #include <smbsrv/smbinfo.h>
39 #include <smb/ntaccess.h>
40 #include <smbsrv/ntlocale.h>
41 #include <smbsrv/string.h>
42 #include <lsalib.h>
43
44 /*
45 * The maximum number of bytes we are prepared to deal with in a
46 * response.
47 */
48 #define MLSVC_MAX_RESPONSE_LEN 1024
49
50 /*
51 * This structure is used when looking up names. We only lookup one
52 * name at a time but the structure will allow for more.
53 */
54 typedef struct lsa_names {
55 uint32_t n_entry;
56 mslsa_string_t name[8];
57 } lsa_names_t;
58
59 typedef DWORD (*lsar_nameop_t)(mlsvc_handle_t *, lsa_names_t *,
366 }
367 }
368
369 ndr_rpc_release(lsa_handle);
370 return (status);
371 }
372
373 /*
374 * Lookup a name and obtain the sid/rid.
375 * This is a wrapper for the various lookup sid RPCs.
376 */
377 uint32_t
378 lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
379 {
380 static lsar_nameop_t ops[] = {
381 lsar_lookup_names3,
382 lsar_lookup_names2,
383 lsar_lookup_names1
384 };
385
386 lsa_names_t names;
387 char *p;
388 uint32_t length;
389 uint32_t status = NT_STATUS_INVALID_PARAMETER;
390 int n_op = (sizeof (ops) / sizeof (ops[0]));
391 int i;
392
393 if (lsa_handle == NULL || name == NULL || info == NULL)
394 return (NT_STATUS_INVALID_PARAMETER);
395
396 bzero(info, sizeof (smb_account_t));
397
398 /*
399 * Windows 2000 (or later) doesn't like an LSA lookup for
400 * DOMAIN\Administrator.
401 */
402 if ((p = strchr(name, '\\')) != 0) {
403 ++p;
404
405 if (strcasecmp(p, "administrator") == 0)
406 name = p;
407 }
408
409 length = smb_wcequiv_strlen(name);
410 names.name[0].length = length;
411 names.name[0].allosize = length;
412 names.name[0].str = (unsigned char *)name;
413 names.n_entry = 1;
414
415 for (i = 0; i < n_op; ++i) {
416 ndr_rpc_set_nonull(lsa_handle);
417 status = (*ops[i])(lsa_handle, &names, info);
418
419 if (status != NT_STATUS_INVALID_PARAMETER)
420 break;
421 }
422
423 if (status == NT_STATUS_SUCCESS) {
424 info->a_name = lsar_get_username(name);
425
426 if (!smb_account_validate(info)) {
427 smb_account_free(info);
428 status = NT_STATUS_NO_MEMORY;
429 } else {
430 smb_account_trace(info);
431 }
432 }
433
434 return (status);
435 }
436
437 /*
438 * The name may be in one of the following forms:
439 *
440 * domain\username
441 * domain/username
698
699 /*
700 * Lookup a sid and obtain the domain sid and account name.
701 * This is a wrapper for the various lookup sid RPCs.
702 */
703 uint32_t
704 lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
705 smb_account_t *account)
706 {
707 char sidbuf[SMB_SID_STRSZ];
708 uint32_t status;
709
710 if (lsa_handle == NULL || sid == NULL || account == NULL)
711 return (NT_STATUS_INVALID_PARAMETER);
712
713 bzero(account, sizeof (smb_account_t));
714 bzero(sidbuf, SMB_SID_STRSZ);
715 smb_sid_tostr(sid, sidbuf);
716 smb_tracef("%s", sidbuf);
717
718 status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid, account);
719 if (status == RPC_NT_PROCNUM_OUT_OF_RANGE)
720 status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
721 account);
722
723 if (status == NT_STATUS_SUCCESS) {
724 if (!smb_account_validate(account)) {
725 smb_account_free(account);
726 status = NT_STATUS_NO_MEMORY;
727 } else {
728 smb_account_trace(account);
729 }
730 }
731
732 return (status);
733 }
734
735 /*
736 * lsar_lookup_sids1
737 */
738 static uint32_t
739 lsar_lookup_sids1(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid,
1137 * a policy handle.
1138 */
1139 int
1140 lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name,
1141 struct ms_luid *luid)
1142 {
1143 struct mslsa_LookupPrivValue arg;
1144 int opnum;
1145 int rc;
1146 size_t length;
1147
1148 if (lsa_handle == NULL || name == NULL || luid == NULL)
1149 return (-1);
1150
1151 opnum = LSARPC_OPNUM_LookupPrivValue;
1152
1153 bzero(&arg, sizeof (struct mslsa_LookupPrivValue));
1154 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
1155
1156 length = smb_wcequiv_strlen(name);
1157 length += sizeof (smb_wchar_t);
1158
1159 arg.name.length = length;
1160 arg.name.allosize = length;
1161 arg.name.str = (unsigned char *)name;
1162
1163 rc = ndr_rpc_call(lsa_handle, opnum, &arg);
1164 if (rc == 0) {
1165 if (arg.status != 0)
1166 rc = -1;
1167 else
1168 (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid));
1169 }
1170
1171 ndr_rpc_release(lsa_handle);
1172 return (rc);
1173 }
1174
1175 /*
1176 * lsar_lookup_priv_name
|