summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorAlan Wright <amw@Sun.COM>2010-01-07 12:22:14 -0800
committerAlan Wright <amw@Sun.COM>2010-01-07 12:22:14 -0800
commitf96bd5c800e73e351b0b6e4bd7f00b578dad29bb (patch)
treeef8fdc0a1b5608418352112c5e2878ed67ba5c50 /usr/src/lib
parent930af642678ee3facd16f9ced3f72a773a8889bd (diff)
downloadillumos-gate-f96bd5c800e73e351b0b6e4bd7f00b578dad29bb.tar.gz
6910821 cifs.d needs updated to reflect changes to smb_fqi_t
6911288 NDR support for reference pointers in conformant arrays 6848220 smbsrv should fill uio_extflg 6899409 Preserve owner@/group@ across SMB 6912791 Unable to set sharename using zfs set sharesmb=name=<value>
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libshare/smb/libshare_smb.c10
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c72
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c171
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c7
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c61
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h7
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers3
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_acl.c64
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_idmap.c20
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_sd.c8
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_wksids.c40
11 files changed, 345 insertions, 118 deletions
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c
index 2ad4872253..64df6d9f16 100644
--- a/usr/src/lib/libshare/smb/libshare_smb.c
+++ b/usr/src/lib/libshare/smb/libshare_smb.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1616,6 +1616,9 @@ fix_resource_name(sa_share_t share, char *name, char *prefix)
size_t bufsz = SA_MAX_RESOURCE_NAME + 1;
size_t prelen;
+ if (prefix == NULL)
+ return (strdup(name));
+
dataset = sa_get_share_attr(share, "dataset");
if (dataset == NULL)
return (strdup(name));
@@ -1776,9 +1779,8 @@ smb_parse_optstring(sa_group_t group, char *options)
"prefix", prefix);
}
}
- if (prefix != NULL)
- name = fix_resource_name(
- (sa_share_t)group, value, prefix);
+ name = fix_resource_name((sa_share_t)group,
+ value, prefix);
if (name != NULL) {
resource = sa_add_resource(
(sa_share_t)group, name,
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
index ebc66c0810..dc6c8a2c51 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,7 +39,7 @@
#include <smbsrv/string.h>
#include <smbsrv/libmlrpc.h>
-#define NDR_STRING_MAX 256
+#define NDR_STRING_MAX 4096
#define NDR_IS_UNION(T) \
(((T)->type_flags & NDR_F_TYPEOP_MASK) == NDR_F_UNION)
@@ -623,12 +623,14 @@ ndr_outer(ndr_ref_t *outer_ref)
case NDR_F_SIZE_IS:
case NDR_F_DIMENSION_IS:
+ case NDR_F_IS_POINTER+NDR_F_SIZE_IS:
+ case NDR_F_IS_REFERENCE+NDR_F_SIZE_IS:
if (is_varlen) {
error = NDR_ERR_ARRAY_VARLEN_ILLEGAL;
break;
}
- if (params == NDR_F_SIZE_IS)
+ if (params & NDR_F_SIZE_IS)
return (ndr_outer_conformant_array(outer_ref));
else
return (ndr_outer_fixed_array(outer_ref));
@@ -694,9 +696,8 @@ ndr_outer_fixed(ndr_ref_t *outer_ref)
case NDR_M_OP_MARSHALL:
valp = outer_ref->datum;
assert(valp);
- if (outer_ref->backptr) {
+ if (outer_ref->backptr)
assert(valp == *outer_ref->backptr);
- }
break;
case NDR_M_OP_UNMARSHALL:
@@ -782,9 +783,8 @@ ndr_outer_fixed_array(ndr_ref_t *outer_ref)
case NDR_M_OP_MARSHALL:
valp = outer_ref->datum;
assert(valp);
- if (outer_ref->backptr) {
+ if (outer_ref->backptr)
assert(valp == *outer_ref->backptr);
- }
break;
case NDR_M_OP_UNMARSHALL:
@@ -841,12 +841,13 @@ ndr_outer_conformant_array(ndr_ref_t *outer_ref)
unsigned n_variable;
unsigned n_alloc;
unsigned n_pdu_total;
+ unsigned n_ptr_offset;
int params;
params = outer_ref->outer_flags & NDR_F_PARAMS_MASK;
assert(!is_varlen && !is_string && !is_union);
- assert(params == NDR_F_SIZE_IS);
+ assert(params & NDR_F_SIZE_IS);
/* conformant header for this */
n_hdr = 4;
@@ -877,20 +878,28 @@ ndr_outer_conformant_array(ndr_ref_t *outer_ref)
valp = outer_ref->datum;
assert(valp);
- if (outer_ref->backptr) {
+ if (outer_ref->backptr)
assert(valp == *outer_ref->backptr);
- }
+ n_ptr_offset = 4;
break;
case NDR_M_OP_UNMARSHALL:
- rc = ndr_outer_peek_sizing(outer_ref, 0, &size_is);
- if (!rc)
- return (0); /* error already set */
+ if (params & NDR_F_IS_REFERENCE) {
+ size_is = outer_ref->size_is;
+ n_ptr_offset = 0;
+ } else {
+ /* NDR_F_IS_POINTER */
+ rc = ndr_outer_peek_sizing(outer_ref, 0, &size_is);
+ if (!rc)
+ return (0); /* error already set */
+
+ if (size_is != outer_ref->size_is) {
+ NDR_SET_ERROR(outer_ref,
+ NDR_ERR_SIZE_IS_MISMATCH_PDU);
+ return (0);
+ }
- if (size_is != outer_ref->size_is) {
- NDR_SET_ERROR(outer_ref,
- NDR_ERR_SIZE_IS_MISMATCH_PDU);
- return (0);
+ n_ptr_offset = 4;
}
if (size_is > 0) {
@@ -929,7 +938,7 @@ ndr_outer_conformant_array(ndr_ref_t *outer_ref)
myref.inner_flags = NDR_F_DIMENSION_IS; /* convenient */
myref.dimension_is = outer_ref->size_is; /* convenient */
- myref.pdu_offset = outer_ref->pdu_offset + 4;
+ myref.pdu_offset = outer_ref->pdu_offset + n_ptr_offset;
rc = ndr_inner(&myref);
if (!rc)
@@ -998,9 +1007,8 @@ ndr_outer_conformant_construct(ndr_ref_t *outer_ref)
valp = outer_ref->datum;
assert(valp);
- if (outer_ref->backptr) {
+ if (outer_ref->backptr)
assert(valp == *outer_ref->backptr);
- }
break;
case NDR_M_OP_UNMARSHALL:
@@ -1202,7 +1210,7 @@ ndr_outer_string(ndr_ref_t *outer_ref)
} else {
valp = outer_ref->datum;
n_zeroes = 0;
- for (ix = 0; ix < 1024; ix++) {
+ for (ix = 0; ix < NDR_STRING_MAX; ix++) {
if (valp[ix] == 0) {
n_zeroes++;
if (n_zeroes >= is_varlen &&
@@ -1213,7 +1221,7 @@ ndr_outer_string(ndr_ref_t *outer_ref)
n_zeroes = 0;
}
}
- if (ix >= 1024) {
+ if (ix >= NDR_STRING_MAX) {
NDR_SET_ERROR(outer_ref, NDR_ERR_STRLEN);
return (0);
}
@@ -1614,15 +1622,19 @@ ndr_inner_pointer(ndr_ref_t *arg_ref)
if (!outer_ref)
return (0); /* error already set */
- /* move advice in inner_flags to outer_flags sans pointer */
+ /*
+ * Move advice in inner_flags to outer_flags.
+ * Retain pointer flag for conformant arrays.
+ */
outer_ref->outer_flags = arg_ref->inner_flags & NDR_F_PARAMS_MASK;
- outer_ref->outer_flags &= ~NDR_F_IS_POINTER;
-#ifdef NDR_INNER_NOT_YET
+ if ((outer_ref->outer_flags & NDR_F_SIZE_IS) == 0)
+ outer_ref->outer_flags &= ~NDR_F_IS_POINTER;
+#ifdef NDR_INNER_PTR_NOT_YET
outer_ref->outer_flags |= NDR_F_BACKPTR;
if (outer_ref->outer_flags & NDR_F_SIZE_IS) {
outer_ref->outer_flags |= NDR_F_ARRAY+NDR_F_CONFORMANT;
}
-#endif /* NDR_INNER_NOT_YET */
+#endif /* NDR_INNER_PTR_NOT_YET */
outer_ref->backptr = valpp;
@@ -1657,9 +1669,13 @@ ndr_inner_reference(ndr_ref_t *arg_ref)
if (!outer_ref)
return (0); /* error already set */
- /* move advice in inner_flags to outer_flags sans pointer */
+ /*
+ * Move advice in inner_flags to outer_flags.
+ * Retain reference flag for conformant arrays.
+ */
outer_ref->outer_flags = arg_ref->inner_flags & NDR_F_PARAMS_MASK;
- outer_ref->outer_flags &= ~NDR_F_IS_REFERENCE;
+ if ((outer_ref->outer_flags & NDR_F_SIZE_IS) == 0)
+ outer_ref->outer_flags &= ~NDR_F_IS_REFERENCE;
#ifdef NDR_INNER_REF_NOT_YET
outer_ref->outer_flags |= NDR_F_BACKPTR;
if (outer_ref->outer_flags & NDR_F_SIZE_IS) {
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
index d8a477ef6e..53bfc89dd4 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -523,6 +523,15 @@ samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
}
/*
+ * QueryInfoDomain2: Identical to QueryDomainInfo.
+ */
+static int
+samr_s_QueryInfoDomain2(void *arg, ndr_xa_t *mxa)
+{
+ return (samr_s_QueryDomainInfo(arg, mxa));
+}
+
+/*
* Looks up the given name in the specified domain which could
* be either the built-in or local domain.
*
@@ -567,7 +576,7 @@ samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
switch (data->kd_type) {
case SMB_DOMAIN_BUILTIN:
- wka = smb_wka_lookup_name((char *)param->name.str);
+ wka = smb_wka_lookup_builtin((char *)param->name.str);
if (wka != NULL) {
param->rids.n_entry = 1;
(void) smb_sid_getrid(wka->wka_binsid,
@@ -904,16 +913,17 @@ samr_s_Connect(void *arg, ndr_xa_t *mxa)
/*
* samr_s_GetUserPwInfo
*
- * This is a request to get a user's password.
+ * Request for a user's password policy information.
*/
/*ARGSUSED*/
static int
samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa)
{
- struct samr_GetUserPwInfo *param = arg;
+ static samr_password_info_t pwinfo;
+ struct samr_GetUserPwInfo *param = arg;
- bzero(param, sizeof (struct samr_GetUserPwInfo));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ param->pwinfo = &pwinfo;
+ param->status = NT_STATUS_SUCCESS;
return (NDR_DRC_OK);
}
@@ -947,15 +957,18 @@ samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa)
/*
* samr_s_GetDomainPwInfo
+ *
+ * Request for the domain password policy information.
*/
/*ARGSUSED*/
static int
samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa)
{
- struct samr_GetDomainPwInfo *param = arg;
+ static samr_password_info_t pwinfo;
+ struct samr_GetDomainPwInfo *param = arg;
- bzero(param, sizeof (struct samr_GetDomainPwInfo));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ param->pwinfo = &pwinfo;
+ param->status = NT_STATUS_SUCCESS;
return (NDR_DRC_OK);
}
@@ -1177,11 +1190,16 @@ static int
samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
{
struct samr_OpenAlias *param = arg;
- ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
- ndr_handle_t *hd;
- uint32_t status;
- samr_keydata_t *data;
- int rc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_gdomain_t gd_type;
+ smb_sid_t *sid;
+ smb_wka_t *wka;
+ char sidstr[SMB_SID_STRSZ];
+ uint32_t rid;
+ uint32_t status;
+ int rc;
if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
status = NT_STATUS_INVALID_HANDLE;
@@ -1194,8 +1212,36 @@ samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
}
data = (samr_keydata_t *)hd->nh_data;
- rc = smb_lgrp_getbyrid(param->rid, (smb_gdomain_t)data->kd_type, NULL);
- if (rc != SMB_LGRP_SUCCESS) {
+ gd_type = (smb_gdomain_t)data->kd_type;
+ rid = param->rid;
+
+ switch (gd_type) {
+ case SMB_LGRP_BUILTIN:
+ (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
+ NT_BUILTIN_DOMAIN_SIDSTR, rid);
+ if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto open_alias_err;
+ }
+
+ wka = smb_wka_lookup_sid(sid);
+ smb_sid_free(sid);
+
+ if (wka == NULL) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto open_alias_err;
+ }
+ break;
+
+ case SMB_LGRP_LOCAL:
+ rc = smb_lgrp_getbyrid(rid, gd_type, NULL);
+ if (rc != SMB_LGRP_SUCCESS) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto open_alias_err;
+ }
+ break;
+
+ default:
status = NT_STATUS_NO_SUCH_ALIAS;
goto open_alias_err;
}
@@ -1313,12 +1359,19 @@ static int
samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
{
struct samr_QueryAliasInfo *param = arg;
- ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
- ndr_handle_t *hd;
- samr_keydata_t *data;
- smb_group_t grp;
- uint32_t status;
- int rc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ smb_gdomain_t gd_type;
+ smb_sid_t *sid;
+ smb_wka_t *wka;
+ char sidstr[SMB_SID_STRSZ];
+ char *name;
+ char *desc;
+ uint32_t rid;
+ uint32_t status;
+ int rc;
if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
status = NT_STATUS_INVALID_HANDLE;
@@ -1326,9 +1379,41 @@ samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
}
data = (samr_keydata_t *)hd->nh_data;
- rc = smb_lgrp_getbyrid(data->kd_rid, (smb_gdomain_t)data->kd_type,
- &grp);
- if (rc != SMB_LGRP_SUCCESS) {
+ gd_type = (smb_gdomain_t)data->kd_type;
+ rid = data->kd_rid;
+
+ switch (gd_type) {
+ case SMB_LGRP_BUILTIN:
+ (void) snprintf(sidstr, SMB_SID_STRSZ, "%s-%d",
+ NT_BUILTIN_DOMAIN_SIDSTR, rid);
+ if ((sid = smb_sid_fromstr(sidstr)) == NULL) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto query_alias_err;
+ }
+
+ wka = smb_wka_lookup_sid(sid);
+ smb_sid_free(sid);
+
+ if (wka == NULL) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto query_alias_err;
+ }
+
+ name = wka->wka_name;
+ desc = (wka->wka_desc != NULL) ? wka->wka_desc : "";
+ break;
+
+ case SMB_LGRP_LOCAL:
+ rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto query_alias_err;
+ }
+ name = grp.sg_name;
+ desc = grp.sg_cmnt;
+ break;
+
+ default:
status = NT_STATUS_NO_SUCH_ALIAS;
goto query_alias_err;
}
@@ -1336,10 +1421,10 @@ samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
switch (param->level) {
case SAMR_QUERY_ALIAS_INFO_1:
param->ru.info1.level = param->level;
- (void) NDR_MSTRING(mxa, grp.sg_name,
+ (void) NDR_MSTRING(mxa, name,
(ndr_mstring_t *)&param->ru.info1.name);
- (void) NDR_MSTRING(mxa, grp.sg_cmnt,
+ (void) NDR_MSTRING(mxa, desc,
(ndr_mstring_t *)&param->ru.info1.desc);
param->ru.info1.unknown = 1;
@@ -1347,17 +1432,19 @@ samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa)
case SAMR_QUERY_ALIAS_INFO_3:
param->ru.info3.level = param->level;
- (void) NDR_MSTRING(mxa, grp.sg_cmnt,
+ (void) NDR_MSTRING(mxa, desc,
(ndr_mstring_t *)&param->ru.info3.desc);
break;
default:
- smb_lgrp_free(&grp);
+ if (gd_type == SMB_LGRP_LOCAL)
+ smb_lgrp_free(&grp);
status = NT_STATUS_INVALID_INFO_CLASS;
goto query_alias_err;
};
- smb_lgrp_free(&grp);
+ if (gd_type == SMB_LGRP_LOCAL)
+ smb_lgrp_free(&grp);
param->address = (DWORD)(uintptr_t)&param->ru;
param->status = 0;
return (NDR_DRC_OK);
@@ -1511,23 +1598,24 @@ samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa)
/*
* samr_s_Connect3
- *
- * This is the connect3 form of the connect request. It contains an
- * extra parameter over samr_Connect. See samr_s_Connect for other
- * details. NT returns an RPC fault - so we can do the same for now.
- * Doing it this way should avoid the unsupported opnum error message
- * appearing in the log.
*/
-/*ARGSUSED*/
static int
samr_s_Connect3(void *arg, ndr_xa_t *mxa)
{
- struct samr_Connect3 *param = arg;
+ struct samr_Connect3 *param = arg;
+ ndr_hdid_t *id;
- bzero(param, sizeof (struct samr_Connect3));
- return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID);
-}
+ id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
+ if (id) {
+ bcopy(id, &param->handle, sizeof (samr_handle_t));
+ param->status = 0;
+ } else {
+ bzero(&param->handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
+ return (NDR_DRC_OK);
+}
/*
* samr_s_Connect4
@@ -1552,6 +1640,7 @@ static ndr_stub_table_t samr_stub_table[] = {
{ samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains },
{ samr_s_OpenDomain, SAMR_OPNUM_OpenDomain },
{ samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo },
+ { samr_s_QueryInfoDomain2, SAMR_OPNUM_QueryInfoDomain2 },
{ samr_s_LookupNames, SAMR_OPNUM_LookupNames },
{ samr_s_OpenUser, SAMR_OPNUM_OpenUser },
{ samr_s_DeleteUser, SAMR_OPNUM_DeleteUser },
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c
index 4b92b5dc58..5ee879eb36 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,9 +40,10 @@
#define SRVSVC_ACE_OFFSET 8
#define SRVSVC_SID_OFFSET 8
+uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
+
static uint32_t srvsvc_sd_get_autohome(const smb_share_t *, smb_sd_t *);
static uint32_t srvsvc_sd_status_to_error(uint32_t);
-static uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
static uint32_t srvsvc_sd_set_absolute(uint8_t *, smb_sd_t *);
/*
@@ -259,7 +260,7 @@ srvsvc_acl_set_relative(uint8_t *sdbuf, smb_acl_t *acl)
*
* Returns Win32 error codes.
*/
-static uint32_t
+uint32_t
srvsvc_sd_set_relative(smb_sd_t *sd, uint8_t *sdbuf)
{
mslm_security_descriptor_t *msd;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c
index 72905f709a..c2f0814025 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -94,6 +94,8 @@ static winreg_keylist_t winreg_keylist;
static boolean_t winreg_key_has_subkey(const char *);
static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t);
static char *winreg_lookup_value(const char *);
+static uint32_t winreg_sd_format(smb_sd_t *);
+uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
static int winreg_s_OpenHKCR(void *, ndr_xa_t *);
static int winreg_s_OpenHKCU(void *, ndr_xa_t *);
@@ -633,17 +635,70 @@ winreg_s_FlushKey(void *arg, ndr_xa_t *mxa)
/*
* winreg_s_GetKeySec
*/
-/*ARGSUSED*/
static int
winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa)
{
struct winreg_GetKeySec *param = arg;
+ struct winreg_value *sd_buf;
+ smb_sd_t sd;
+ uint32_t sd_len;
+ uint32_t status;
+
+ bzero(&sd, sizeof (smb_sd_t));
+
+ if ((status = winreg_sd_format(&sd)) != ERROR_SUCCESS)
+ goto winreg_getkeysec_error;
+
+ sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
+
+ param->sd = NDR_MALLOC(mxa, sizeof (struct winreg_secdesc));
+ if (param->sd == NULL) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto winreg_getkeysec_error;
+ }
+
+ param->sd->sd_len = sd_len;
+ param->sd->sd_size = sd_len;
+
+ sd_buf = NDR_MALLOC(mxa, sd_len + sizeof (struct winreg_value));
+ param->sd->sd_buf = sd_buf;
+ sd_buf->vc_first_is = 0;
+ sd_buf->vc_length_is = sd_len;
+ param->status = srvsvc_sd_set_relative(&sd, sd_buf->value);
+
+ smb_sd_term(&sd);
+ return (NDR_DRC_OK);
+
+winreg_getkeysec_error:
+ smb_sd_term(&sd);
bzero(param, sizeof (struct winreg_GetKeySec));
- param->status = ERROR_ACCESS_DENIED;
+ param->status = status;
return (NDR_DRC_OK);
}
+static uint32_t
+winreg_sd_format(smb_sd_t *sd)
+{
+ smb_fssd_t fs_sd;
+ acl_t *acl;
+ uint32_t status = ERROR_SUCCESS;
+
+ if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0)
+ return (ERROR_NOT_ENOUGH_MEMORY);
+
+ smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
+ fs_sd.sd_uid = 0;
+ fs_sd.sd_gid = 0;
+ fs_sd.sd_zdacl = acl;
+ fs_sd.sd_zsacl = NULL;
+
+ if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS)
+ status = ERROR_ACCESS_DENIED;
+ smb_fssd_term(&fs_sd);
+ return (status);
+}
+
/*
* winreg_s_NotifyChange
*/
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index f9acbec34c..e8d0ed396f 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -815,9 +815,10 @@ typedef struct smb_wka {
*/
int smb_wka_init(void);
void smb_wka_fini(void);
-smb_wka_t *smb_wka_lookup_name(char *);
+smb_wka_t *smb_wka_lookup_builtin(const char *);
+smb_wka_t *smb_wka_lookup_name(const char *);
smb_wka_t *smb_wka_lookup_sid(smb_sid_t *);
-smb_sid_t *smb_wka_get_sid(char *);
+smb_sid_t *smb_wka_get_sid(const char *);
char *smb_wka_get_domain(int);
uint32_t smb_wka_token_groups(uint32_t, smb_ids_t *);
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 43e39c72da..fa8740097e 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -18,7 +18,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -380,6 +380,7 @@ SUNWprivate {
smb_wka_get_domain;
smb_wka_get_sid;
smb_wka_init;
+ smb_wka_lookup_builtin;
smb_wka_lookup_name;
smb_wka_lookup_sid;
smb_wka_token_groups;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_acl.c b/usr/src/lib/smbsrv/libsmb/common/smb_acl.c
index 9d981ceeb4..df5bc7cfb3 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_acl.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_acl.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,25 +45,16 @@
#define SMB_AG_DNY_DRCT 3
#define SMB_AG_NUM 4
-/*
- * SID for Everyone group: S-1-1-0.
- */
-smb_sid_t everyone_sid = {
- NT_SID_REVISION,
- 1,
- NT_SECURITY_WORLD_AUTH,
- { 0 }
-};
-
#define DEFAULT_DACL_ACENUM 2
acl_t *acl_alloc(enum acl_type);
-static idmap_stat smb_fsacl_getsids(smb_idmap_batch_t *, acl_t *, uid_t, gid_t);
+static idmap_stat smb_fsacl_getsids(smb_idmap_batch_t *, acl_t *);
static acl_t *smb_fsacl_null_empty(boolean_t);
static uint16_t smb_ace_len(smb_ace_t *);
static uint32_t smb_ace_mask_g2s(uint32_t);
static uint16_t smb_ace_flags_tozfs(uint8_t);
static uint8_t smb_ace_flags_fromzfs(uint16_t);
+static boolean_t smb_ace_wellknown_update(const char *, ace_t *);
smb_acl_t *
smb_acl_alloc(uint8_t revision, uint16_t bsize, uint16_t acecnt)
@@ -245,7 +236,7 @@ smb_acl_sort(smb_acl_t *acl)
* returned upon successful conversion.
*/
smb_acl_t *
-smb_acl_from_zfs(acl_t *zacl, uid_t uid, gid_t gid)
+smb_acl_from_zfs(acl_t *zacl)
{
ace_t *zace;
int numaces;
@@ -260,7 +251,7 @@ smb_acl_from_zfs(acl_t *zacl, uid_t uid, gid_t gid)
if (idm_stat != IDMAP_SUCCESS)
return (NULL);
- if (smb_fsacl_getsids(&sib, zacl, uid, gid) != IDMAP_SUCCESS) {
+ if (smb_fsacl_getsids(&sib, zacl) != IDMAP_SUCCESS) {
smb_idmap_batch_destroy(&sib);
return (NULL);
}
@@ -308,6 +299,7 @@ smb_acl_from_zfs(acl_t *zacl, uid_t uid, gid_t gid)
uint32_t
smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
{
+ char sidstr[SMB_SID_STRSZ];
smb_ace_t *ace;
acl_t *zacl;
ace_t *zace;
@@ -345,13 +337,14 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES;
zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask);
zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags);
+ zace->a_who = (uid_t)-1;
- if (smb_sid_cmp(ace->se_sid, &everyone_sid))
- zace->a_flags |= ACE_EVERYONE;
- else {
+ smb_sid_tostr(ace->se_sid, sidstr);
+
+ if (!smb_ace_wellknown_update(sidstr, zace)) {
sim->sim_id = &zace->a_who;
idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim,
- ace->se_sid, -1);
+ ace->se_sid, SMB_IDMAP_UNKNOWN);
if (idm_stat != IDMAP_SUCCESS) {
smb_fsacl_free(zacl);
@@ -375,7 +368,7 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
ace = acl->sl_aces;
sim = sib.sib_maps;
for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) {
- if (zace->a_flags & ACE_EVERYONE)
+ if (zace->a_who == (uid_t)-1)
continue;
if (sim->sim_idtype == SMB_IDMAP_GROUP)
@@ -388,13 +381,38 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
return (NT_STATUS_SUCCESS);
}
+static boolean_t
+smb_ace_wellknown_update(const char *sid, ace_t *zace)
+{
+ struct {
+ char *sid;
+ uint16_t flags;
+ } map[] = {
+ { NT_WORLD_SIDSTR, ACE_EVERYONE },
+ { NT_BUILTIN_CURRENT_OWNER_SIDSTR, ACE_OWNER },
+ { NT_BUILTIN_CURRENT_GROUP_SIDSTR,
+ (ACE_GROUP | ACE_IDENTIFIER_GROUP) },
+ };
+
+ int i;
+
+ for (i = 0; i < (sizeof (map) / sizeof (map[0])); ++i) {
+ if (strcmp(sid, map[i].sid) == 0) {
+ zace->a_flags |= map[i].flags;
+ return (B_TRUE);
+ }
+ }
+
+ return (B_FALSE);
+}
+
/*
* smb_fsacl_getsids
*
* Batch all the uid/gid in given ZFS ACL to get their corresponding SIDs.
*/
static idmap_stat
-smb_fsacl_getsids(smb_idmap_batch_t *sib, acl_t *zacl, uid_t uid, gid_t gid)
+smb_fsacl_getsids(smb_idmap_batch_t *sib, acl_t *zacl)
{
ace_t *zace;
idmap_stat idm_stat;
@@ -408,14 +426,12 @@ smb_fsacl_getsids(smb_idmap_batch_t *sib, acl_t *zacl, uid_t uid, gid_t gid)
zace++, i++, sim++) {
switch (zace->a_flags & ACE_TYPE_FLAGS) {
case ACE_OWNER:
- id = uid;
- idtype = SMB_IDMAP_USER;
+ idtype = SMB_IDMAP_OWNERAT;
break;
case (ACE_GROUP | ACE_IDENTIFIER_GROUP):
/* owning group */
- id = gid;
- idtype = SMB_IDMAP_GROUP;
+ idtype = SMB_IDMAP_GROUPAT;
break;
case ACE_IDENTIFIER_GROUP:
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
index 9da309a7c6..a972059ef4 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -348,9 +348,25 @@ smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
&sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
break;
+ case SMB_IDMAP_OWNERAT:
+ /* Current Owner S-1-5-32-766 */
+ sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
+ sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
+ sim->sim_stat = IDMAP_SUCCESS;
+ stat = IDMAP_SUCCESS;
+ break;
+
+ case SMB_IDMAP_GROUPAT:
+ /* Current Group S-1-5-32-767 */
+ sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
+ sim->sim_rid = SECURITY_CURRENT_GROUP_RID;
+ sim->sim_stat = IDMAP_SUCCESS;
+ stat = IDMAP_SUCCESS;
+ break;
+
case SMB_IDMAP_EVERYONE:
/* Everyone S-1-1-0 */
- sim->sim_domsid = strdup("S-1-1");
+ sim->sim_domsid = strdup(NT_WORLD_AUTH_SIDSTR);
sim->sim_rid = 0;
sim->sim_stat = IDMAP_SUCCESS;
stat = IDMAP_SUCCESS;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sd.c b/usr/src/lib/smbsrv/libsmb/common/smb_sd.c
index af9171ce1d..f8007c454e 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_sd.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_sd.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -425,8 +425,7 @@ smb_sd_fromfs(smb_fssd_t *fs_sd, smb_sd_t *sd)
/* DACL */
if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) {
if (fs_sd->sd_zdacl != NULL) {
- acl = smb_acl_from_zfs(fs_sd->sd_zdacl, fs_sd->sd_uid,
- fs_sd->sd_gid);
+ acl = smb_acl_from_zfs(fs_sd->sd_zdacl);
if (acl == NULL) {
smb_sd_term(sd);
return (NT_STATUS_INTERNAL_ERROR);
@@ -448,8 +447,7 @@ smb_sd_fromfs(smb_fssd_t *fs_sd, smb_sd_t *sd)
/* SACL */
if (fs_sd->sd_secinfo & SMB_SACL_SECINFO) {
if (fs_sd->sd_zsacl != NULL) {
- acl = smb_acl_from_zfs(fs_sd->sd_zsacl, fs_sd->sd_uid,
- fs_sd->sd_gid);
+ acl = smb_acl_from_zfs(fs_sd->sd_zsacl);
if (acl == NULL) {
smb_sd_term(sd);
return (NT_STATUS_INTERNAL_ERROR);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c b/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c
index ef9400b785..58cc60918e 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,6 +60,8 @@ static smb_wka_t wka_tbl[] = {
SidTypeWellKnownGroup, 0, NULL, NULL },
{ 0, "S-1-3-4", "Owner Rights",
SidTypeWellKnownGroup, 0, NULL, NULL },
+ { 0, "S-1-3-5", "Group Rights",
+ SidTypeWellKnownGroup, 0, NULL, NULL },
{ 1, "S-1-5", "NT Pseudo Domain",
SidTypeDomain, 0, NULL, NULL },
{ 2, "S-1-5-1", "Dialup",
@@ -124,7 +126,11 @@ static smb_wka_t wka_tbl[] = {
SMB_WKAFLG_LGRP_ENABLE,
"Members can bypass file security to back up files", NULL },
{ 3, "S-1-5-32-552", "Replicator",
- SidTypeAlias, 0, NULL, NULL }
+ SidTypeAlias, 0, NULL, NULL },
+ { 3, "S-1-5-32-766", "Current Owner",
+ SidTypeAlias, 0, NULL, NULL },
+ { 3, "S-1-5-32-767", "Current Group",
+ SidTypeAlias, 0, NULL, NULL },
};
#define SMB_WKA_NUM (sizeof (wka_tbl)/sizeof (wka_tbl[0]))
@@ -161,7 +167,7 @@ smb_wka_lookup_sid(smb_sid_t *sid)
* entry, otherwise returns NULL.
*/
smb_sid_t *
-smb_wka_get_sid(char *name)
+smb_wka_get_sid(const char *name)
{
smb_wka_t *entry;
smb_sid_t *sid = NULL;
@@ -178,7 +184,7 @@ smb_wka_get_sid(char *name)
* the table, otherwise returns NULL.
*/
smb_wka_t *
-smb_wka_lookup_name(char *name)
+smb_wka_lookup_name(const char *name)
{
smb_wka_t *entry;
int i;
@@ -197,6 +203,32 @@ smb_wka_lookup_name(char *name)
}
/*
+ * Lookup a name in the BUILTIN domain.
+ */
+smb_wka_t *
+smb_wka_lookup_builtin(const char *name)
+{
+ smb_wka_t *entry;
+ int i;
+
+ (void) rw_rdlock(&wk_rwlock);
+ for (i = 0; i < SMB_WKA_NUM; ++i) {
+ entry = &wka_tbl[i];
+
+ if (entry->wka_domidx != 3)
+ continue;
+
+ if (!smb_strcasecmp(name, entry->wka_name, 0)) {
+ (void) rw_unlock(&wk_rwlock);
+ return (entry);
+ }
+ }
+
+ (void) rw_unlock(&wk_rwlock);
+ return (NULL);
+}
+
+/*
* Returns the Netbios domain name for the given index
*/
char *