Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
1575 untangle libmlrpc from SMB server
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-2667 Wrong error when join domain with wrong password
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server


   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