Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9497 SMB should bypass ACL traverse checking
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3787 Sync. up SMB server with: Merge with illumos-gate 12380e1e
NEX-1440 Unable to take ownership, view permissions, or delete files...
Reviewed by: Alek Pinchuk <alek@nexenta.com>
SMB-56 extended security NTLMSSP, inbound


   3  *
   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  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * Authentication helpers for building credentials
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/sid.h>
  32 #include <sys/priv_names.h>
  33 #include <sys/socket.h>
  34 #include <sys/un.h>
  35 #include <netinet/in.h>
  36 #include <smbsrv/smb_idmap.h>
  37 #include <smbsrv/smb_kproto.h>
  38 #include <smbsrv/smb_token.h>
  39 
  40 static void smb_cred_set_sid(smb_id_t *id, ksid_t *ksid);
  41 static ksidlist_t *smb_cred_set_sidlist(smb_ids_t *token_grps);
  42 
  43 /*
  44  * Allocate a Solaris cred and initialize it based on the access token.
  45  *
  46  * If the user can be mapped to a non-ephemeral ID, the cred gid is set
  47  * to the Solaris user's primary group.
  48  *
  49  * If the mapped UID is ephemeral, or the primary group could not be
  50  * obtained, the cred gid is set to whatever Solaris group is mapped
  51  * to the token's primary group.





  52  */
  53 cred_t *
  54 smb_cred_create(smb_token_t *token)
  55 {
  56         ksid_t                  ksid;
  57         ksidlist_t              *ksidlist = NULL;
  58         smb_posix_grps_t        *posix_grps;
  59         cred_t                  *cr;
  60         gid_t                   gid;

  61 
  62         ASSERT(token);
  63         ASSERT(token->tkn_posix_grps);
  64         posix_grps = token->tkn_posix_grps;
  65 
  66         cr = crget();
  67         ASSERT(cr != NULL);
  68 
  69         if (!IDMAP_ID_IS_EPHEMERAL(token->tkn_user.i_id) &&
  70             (posix_grps->pg_ngrps != 0)) {
  71                 gid = posix_grps->pg_grps[0];
  72         } else {
  73                 gid = token->tkn_primary_grp.i_id;
  74         }
  75 
  76         if (crsetugid(cr, token->tkn_user.i_id, gid) != 0) {
  77                 crfree(cr);
  78                 return (NULL);
  79         }
  80 


  92         ksidlist = smb_cred_set_sidlist(&token->tkn_win_grps);
  93         crsetsidlist(cr, ksidlist);
  94 
  95         /*
  96          * In the AD world, "take ownership privilege" is very much
  97          * like having Unix "root" privileges.  It's normally given
  98          * to members of the "Administrators" group, which normally
  99          * includes the the local Administrator (like root) and when
 100          * joined to a domain, "Domain Admins".
 101          */
 102         if (smb_token_query_privilege(token, SE_TAKE_OWNERSHIP_LUID)) {
 103                 (void) crsetpriv(cr,
 104                     PRIV_FILE_CHOWN,
 105                     PRIV_FILE_DAC_READ,
 106                     PRIV_FILE_DAC_SEARCH,
 107                     PRIV_FILE_DAC_WRITE,
 108                     PRIV_FILE_OWNER,
 109                     NULL);
 110         }
 111 



























 112         return (cr);
 113 }
 114 
 115 /*
 116  * Initialize the ksid based on the given smb_id_t.
 117  */
 118 static void
 119 smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
 120 {
 121         char sidstr[SMB_SID_STRSZ];
 122         int rc;
 123 
 124         ASSERT(id);
 125         ASSERT(id->i_sid);
 126 
 127         ksid->ks_id = id->i_id;
 128         smb_sid_tostr(id->i_sid, sidstr);
 129         rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
 130         ASSERT(rc == 0);
 131 


 137  * Allocate and initialize the ksidlist based on the access token group list.
 138  */
 139 static ksidlist_t *
 140 smb_cred_set_sidlist(smb_ids_t *token_grps)
 141 {
 142         int i;
 143         ksidlist_t *lp;
 144 
 145         lp = kmem_zalloc(KSIDLIST_MEM(token_grps->i_cnt), KM_SLEEP);
 146         lp->ksl_ref = 1;
 147         lp->ksl_nsid = token_grps->i_cnt;
 148         lp->ksl_neid = 0;
 149 
 150         for (i = 0; i < lp->ksl_nsid; i++) {
 151                 smb_cred_set_sid(&token_grps->i_ids[i], &lp->ksl_sids[i]);
 152                 if (lp->ksl_sids[i].ks_id > IDMAP_WK__MAX_GID)
 153                         lp->ksl_neid++;
 154         }
 155 
 156         return (lp);
















 157 }


   3  *
   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  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * Authentication helpers for building credentials
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/sid.h>
  32 #include <sys/priv_names.h>
  33 #include <sys/socket.h>
  34 #include <sys/un.h>
  35 #include <netinet/in.h>
  36 #include <smbsrv/smb_idmap.h>
  37 #include <smbsrv/smb_kproto.h>
  38 #include <smbsrv/smb_token.h>
  39 
  40 static void smb_cred_set_sid(smb_id_t *id, ksid_t *ksid);
  41 static ksidlist_t *smb_cred_set_sidlist(smb_ids_t *token_grps);
  42 
  43 /*
  44  * Allocate a Solaris cred and initialize it based on the access token.
  45  *
  46  * If the user can be mapped to a non-ephemeral ID, the cred gid is set
  47  * to the Solaris user's primary group.
  48  *
  49  * If the mapped UID is ephemeral, or the primary group could not be
  50  * obtained, the cred gid is set to whatever Solaris group is mapped
  51  * to the token's primary group.
  52  *
  53  * Also add any privileges that should always be in effect for this user.
  54  * Note that an SMB user object also gets a u_privcred which is used
  55  * when the client opens an object with "backup/restore intent".
  56  * That cred is setup later, in smb_user_setcred().
  57  */
  58 cred_t *
  59 smb_cred_create(smb_token_t *token, smb_session_t *s)
  60 {
  61         ksid_t                  ksid;
  62         ksidlist_t              *ksidlist = NULL;
  63         smb_posix_grps_t        *posix_grps;
  64         cred_t                  *cr;
  65         gid_t                   gid;
  66         auditinfo_addr_t        *au;
  67 
  68         ASSERT(token);
  69         ASSERT(token->tkn_posix_grps);
  70         posix_grps = token->tkn_posix_grps;
  71 
  72         cr = crget();
  73         ASSERT(cr != NULL);
  74 
  75         if (!IDMAP_ID_IS_EPHEMERAL(token->tkn_user.i_id) &&
  76             (posix_grps->pg_ngrps != 0)) {
  77                 gid = posix_grps->pg_grps[0];
  78         } else {
  79                 gid = token->tkn_primary_grp.i_id;
  80         }
  81 
  82         if (crsetugid(cr, token->tkn_user.i_id, gid) != 0) {
  83                 crfree(cr);
  84                 return (NULL);
  85         }
  86 


  98         ksidlist = smb_cred_set_sidlist(&token->tkn_win_grps);
  99         crsetsidlist(cr, ksidlist);
 100 
 101         /*
 102          * In the AD world, "take ownership privilege" is very much
 103          * like having Unix "root" privileges.  It's normally given
 104          * to members of the "Administrators" group, which normally
 105          * includes the the local Administrator (like root) and when
 106          * joined to a domain, "Domain Admins".
 107          */
 108         if (smb_token_query_privilege(token, SE_TAKE_OWNERSHIP_LUID)) {
 109                 (void) crsetpriv(cr,
 110                     PRIV_FILE_CHOWN,
 111                     PRIV_FILE_DAC_READ,
 112                     PRIV_FILE_DAC_SEARCH,
 113                     PRIV_FILE_DAC_WRITE,
 114                     PRIV_FILE_OWNER,
 115                     NULL);
 116         }
 117 
 118         /*
 119          * See smb.4 bypass_traverse_checking
 120          *
 121          * For historical reasons, the Windows privilege is named
 122          * SeChangeNotifyPrivilege, though the description is
 123          * "Bypass traverse checking".
 124          */
 125         if (smb_token_query_privilege(token, SE_CHANGE_NOTIFY_LUID)) {
 126                 (void) crsetpriv(cr, PRIV_FILE_DAC_SEARCH, NULL);
 127         }
 128 
 129         au = crgetauinfo_modifiable(cr);
 130         if (au != NULL) {
 131                 au->ai_auid = token->tkn_auid;
 132                 au->ai_mask = token->tkn_amask;
 133                 au->ai_asid = token->tkn_asid;
 134                 au->ai_termid.at_port = s->s_local_port;
 135 
 136                 if (s->ipaddr.a_family == AF_INET) {
 137                         au->ai_termid.at_addr[0] = s->ipaddr.a_ipv4;
 138                         au->ai_termid.at_type = AU_IPv4;
 139                 } else {
 140                         bcopy(&s->ipaddr.a_ip, au->ai_termid.at_addr,
 141                             sizeof (in6_addr_t));
 142                         au->ai_termid.at_type = AU_IPv6;
 143                 }
 144         }
 145         return (cr);
 146 }
 147 
 148 /*
 149  * Initialize the ksid based on the given smb_id_t.
 150  */
 151 static void
 152 smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
 153 {
 154         char sidstr[SMB_SID_STRSZ];
 155         int rc;
 156 
 157         ASSERT(id);
 158         ASSERT(id->i_sid);
 159 
 160         ksid->ks_id = id->i_id;
 161         smb_sid_tostr(id->i_sid, sidstr);
 162         rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
 163         ASSERT(rc == 0);
 164 


 170  * Allocate and initialize the ksidlist based on the access token group list.
 171  */
 172 static ksidlist_t *
 173 smb_cred_set_sidlist(smb_ids_t *token_grps)
 174 {
 175         int i;
 176         ksidlist_t *lp;
 177 
 178         lp = kmem_zalloc(KSIDLIST_MEM(token_grps->i_cnt), KM_SLEEP);
 179         lp->ksl_ref = 1;
 180         lp->ksl_nsid = token_grps->i_cnt;
 181         lp->ksl_neid = 0;
 182 
 183         for (i = 0; i < lp->ksl_nsid; i++) {
 184                 smb_cred_set_sid(&token_grps->i_ids[i], &lp->ksl_sids[i]);
 185                 if (lp->ksl_sids[i].ks_id > IDMAP_WK__MAX_GID)
 186                         lp->ksl_neid++;
 187         }
 188 
 189         return (lp);
 190 }
 191 
 192 /*
 193  * Special variant of smb_cred_create() used when we need an
 194  * SMB kcred (i.e. DH import).  The returned cred must be
 195  * from crget() so it can be passed to smb_user_setcred().
 196  */
 197 cred_t *
 198 smb_kcred_create(void)
 199 {
 200         cred_t  *cr;
 201 
 202         cr = crget();
 203         ASSERT(cr != NULL);
 204 
 205         return (cr);
 206 }