diff options
author | Alan Wright <amw@Sun.COM> | 2010-01-07 12:22:14 -0800 |
---|---|---|
committer | Alan Wright <amw@Sun.COM> | 2010-01-07 12:22:14 -0800 |
commit | f96bd5c800e73e351b0b6e4bd7f00b578dad29bb (patch) | |
tree | ef8fdc0a1b5608418352112c5e2878ed67ba5c50 /usr/src/lib | |
parent | 930af642678ee3facd16f9ced3f72a773a8889bd (diff) | |
download | illumos-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.c | 10 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c | 72 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c | 171 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlsvc/common/srvsvc_sd.c | 7 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlsvc/common/winreg_svc.c | 61 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/libsmb.h | 7 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_acl.c | 64 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_idmap.c | 20 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_sd.c | 8 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_wksids.c | 40 |
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 *)¶m->domain_handle; - ndr_handle_t *hd; - uint32_t status; - samr_keydata_t *data; - int rc; + ndr_hdid_t *id = (ndr_hdid_t *)¶m->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 *)¶m->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 *)¶m->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 *)¶m->ru.info1.name); - (void) NDR_MSTRING(mxa, grp.sg_cmnt, + (void) NDR_MSTRING(mxa, desc, (ndr_mstring_t *)¶m->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 *)¶m->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)¶m->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, ¶m->handle, sizeof (samr_handle_t)); + param->status = 0; + } else { + bzero(¶m->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 * |