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 | |
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')
40 files changed, 809 insertions, 597 deletions
diff --git a/usr/src/cmd/smbsrv/dtrace/cifs.d b/usr/src/cmd/smbsrv/dtrace/cifs.d index 3afe93ff01..0e902e7604 100755..100644 --- a/usr/src/cmd/smbsrv/dtrace/cifs.d +++ b/usr/src/cmd/smbsrv/dtrace/cifs.d @@ -20,12 +20,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* #pragma D option flowindent */ @@ -121,7 +119,7 @@ sdt:smbsrv::-smb_op-NtTransactCreate-start { op = (struct open_param *)arg1; - printf("%s", stringof(op->fqi.path)); + printf("%s", stringof(op->fqi.fq_path.pn_path)); } sdt:smbsrv::-smb_op-Open-done, @@ -136,7 +134,7 @@ sdt:smbsrv::-smb_op-NtTransactCreate-done sr = (struct smb_request *)arg0; printf("%s: fid=%u", - stringof(sr->arg.open.fqi.path), sr->smb_fid); + stringof(sr->arg.open.fqi.fq_path.pn_path), sr->smb_fid); } sdt:smbsrv::-smb_op-Read-start, @@ -174,7 +172,8 @@ sdt:smbsrv::-smb_op-Rename-start p = (struct dirop *)arg1; printf("%s to %s", - stringof(p->fqi.path), stringof(p->dst_fqi.path)); + stringof(p->fqi.fq_path.pn_path), + stringof(p->dst_fqi.fq_path.pn_path)); } sdt:smbsrv::-smb_op-CheckDirectory-start, @@ -184,7 +183,7 @@ sdt:smbsrv::-smb_op-Delete-start { p = (struct dirop *)arg1; - printf("%s", stringof(p->fqi.path)); + printf("%s", stringof(p->fqi.fq_path.pn_path)); } /* diff --git a/usr/src/cmd/smbsrv/dtrace/msrpc.d b/usr/src/cmd/smbsrv/dtrace/msrpc.d index 8469bbfa67..15f92ac93e 100644 --- a/usr/src/cmd/smbsrv/dtrace/msrpc.d +++ b/usr/src/cmd/smbsrv/dtrace/msrpc.d @@ -20,7 +20,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. */ @@ -238,6 +238,15 @@ pid$target::lsar_lookup_*:return printf("0x%08x", arg1); } +pid$target::lsar_*:entry +{ +} + +pid$target::lsar_*:return +{ + printf("0x%08x", arg1); +} + /* * NetLogon */ @@ -259,6 +268,7 @@ pid$target::samr_s_LookupDomain:entry, pid$target::samr_s_EnumLocalDomains:entry, pid$target::samr_s_OpenDomain:entry, pid$target::samr_s_QueryDomainInfo:entry, +pid$target::samr_s_QueryInfoDomain2:entry, pid$target::samr_s_LookupNames:entry, pid$target::samr_s_OpenUser:entry, pid$target::samr_s_DeleteUser:entry, @@ -290,6 +300,7 @@ pid$target::samr_s_LookupDomain:return, pid$target::samr_s_EnumLocalDomains:return, pid$target::samr_s_OpenDomain:return, pid$target::samr_s_QueryDomainInfo:return, +pid$target::samr_s_QueryInfoDomain2:return, pid$target::samr_s_LookupNames:return, pid$target::samr_s_OpenUser:return, pid$target::samr_s_DeleteUser:return, 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 * diff --git a/usr/src/uts/common/fs/smbsrv/smb_acl.c b/usr/src/uts/common/fs/smbsrv/smb_acl.c index 75e579a636..f3b3772aea 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_acl.c +++ b/usr/src/uts/common/fs/smbsrv/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. */ @@ -65,16 +65,6 @@ #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 /* * Default ACL: @@ -95,7 +85,7 @@ static ace_t default_dacl[DEFAULT_DACL_ACENUM] = { * format */ -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 int smb_fsacl_inheritable(acl_t *, int); @@ -105,6 +95,7 @@ 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) @@ -291,7 +282,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; @@ -306,7 +297,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); } @@ -360,6 +351,7 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) smb_idmap_batch_t sib; smb_idmap_t *sim; idmap_stat idm_stat; + char *sidstr; int i; ASSERT(fs_acl); @@ -381,6 +373,7 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) if (idm_stat != IDMAP_SUCCESS) return (NT_STATUS_INTERNAL_ERROR); + sidstr = kmem_alloc(SMB_SID_STRSZ, KM_SLEEP); zacl = smb_fsacl_alloc(acl->sl_acecnt, flags); zace = zacl->acl_aclp; @@ -391,15 +384,17 @@ 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) { + kmem_free(sidstr, SMB_SID_STRSZ); smb_fsacl_free(zacl); smb_idmap_batch_destroy(&sib); return (NT_STATUS_INTERNAL_ERROR); @@ -407,6 +402,8 @@ smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) } } + kmem_free(sidstr, SMB_SID_STRSZ); + idm_stat = smb_idmap_batch_getmappings(&sib); if (idm_stat != IDMAP_SUCCESS) { smb_fsacl_free(zacl); @@ -421,7 +418,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) @@ -434,13 +431,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; @@ -454,14 +476,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/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c index 1d3e0c1951..72ab4f1284 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.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. */ @@ -357,6 +357,7 @@ smb_open_subr(smb_request_t *sr) switch (sr->tid_tree->t_res_type & STYPE_MASK) { case STYPE_DISKTREE: + case STYPE_PRINTQ: break; case STYPE_IPC: diff --git a/usr/src/uts/common/fs/smbsrv/smb_create.c b/usr/src/uts/common/fs/smbsrv/smb_create.c index 066b66bb85..6816b07ead 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_create.c +++ b/usr/src/uts/common/fs/smbsrv/smb_create.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. */ @@ -27,8 +27,6 @@ #define SMB_CREATE_NAMEBUF_SZ 16 -static uint32_t smb_common_create(smb_request_t *sr); - /* * Create a new file, or truncate an existing file to zero length, * open the file and return a fid. The file is specified using a diff --git a/usr/src/uts/common/fs/smbsrv/smb_directory.c b/usr/src/uts/common/fs/smbsrv/smb_directory.c index fb4ba9d18a..caab675b86 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_directory.c +++ b/usr/src/uts/common/fs/smbsrv/smb_directory.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. */ @@ -370,7 +370,7 @@ smb_com_check_directory(smb_request_t *sr) char *path; smb_pathname_t *pn; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERROR_ACCESS_DENIED); return (SDRC_ERROR); diff --git a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c index 5c5a6da89b..e406208b3d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.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. */ @@ -246,6 +246,7 @@ smb_mbc_vdecodef(mbuf_chain_t *mbc, char *fmt, va_list ap) vdp->vdb_len = repc; vdp->vdb_uio.uio_iov = &vdp->vdb_iovec[0]; vdp->vdb_uio.uio_iovcnt = MAX_IOVEC; + vdp->vdb_uio.uio_extflg = UIO_COPY_DEFAULT; vdp->vdb_uio.uio_resid = repc; if (mbc_marshal_get_uio(mbc, &vdp->vdb_uio) != 0) return (-1); @@ -261,6 +262,7 @@ smb_mbc_vdecodef(mbuf_chain_t *mbc, char *fmt, va_list ap) vdp->vdb_len = (uint32_t)wval; vdp->vdb_uio.uio_iov = &vdp->vdb_iovec[0]; vdp->vdb_uio.uio_iovcnt = MAX_IOVEC; + vdp->vdb_uio.uio_extflg = UIO_COPY_DEFAULT; vdp->vdb_uio.uio_resid = vdp->vdb_len; if (vdp->vdb_len != 0) { if (mbc_marshal_get_uio(mbc, @@ -1353,6 +1355,7 @@ mbc_marshal_get_uio(mbuf_chain_t *mbc, struct uio *uio) if (bytes != 0) { iov = uio->uio_iov; uio->uio_segflg = UIO_SYSSPACE; + uio->uio_extflg = UIO_COPY_DEFAULT; if (MBC_ROOM_FOR(mbc, bytes) == 0) { /* Data will never be available */ diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c index c5222de5ab..edab276701 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.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. */ @@ -278,7 +278,9 @@ smb_com_nt_create_andx(struct smb_request *sr) if (smb_common_open(sr) != NT_STATUS_SUCCESS) return (SDRC_ERROR); - if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { + switch (sr->tid_tree->t_res_type & STYPE_MASK) { + case STYPE_DISKTREE: + case STYPE_PRINTQ: switch (op->op_oplock_level) { case SMB_OPLOCK_EXCLUSIVE: OplockLevel = 1; @@ -324,8 +326,9 @@ smb_com_nt_create_andx(struct smb_request *sr) op->devstate, DirFlag, 0); - } else { - /* Named PIPE */ + break; + + case STYPE_IPC: OplockLevel = 0; rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlqqqqlqqwwbw", 34, @@ -345,6 +348,12 @@ smb_com_nt_create_andx(struct smb_request *sr) op->devstate, 0, 0); + break; + + default: + smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, + ERRDOS, ERROR_INVALID_FUNCTION); + return (SDRC_ERROR); } return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c index 22786fe92d..dbd4464e22 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.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. */ @@ -189,7 +189,9 @@ smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) if (status != NT_STATUS_SUCCESS) return (SDRC_ERROR); - if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { + switch (sr->tid_tree->t_res_type & STYPE_MASK) { + case STYPE_DISKTREE: + case STYPE_PRINTQ: switch (op->op_oplock_level) { case SMB_OPLOCK_EXCLUSIVE: OplockLevel = 1; @@ -232,8 +234,9 @@ smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) op->ftype, op->devstate, DirFlag); - } else { - /* Named PIPE */ + break; + + case STYPE_IPC: bzero(&attr, sizeof (smb_attr_t)); (void) smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb", 0, @@ -250,6 +253,12 @@ smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) op->ftype, op->devstate, 0); + break; + + default: + smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, + ERRDOS, ERROR_INVALID_FUNCTION); + return (SDRC_ERROR); } return (SDRC_SUCCESS); diff --git a/usr/src/uts/common/fs/smbsrv/smb_ofile.c b/usr/src/uts/common/fs/smbsrv/smb_ofile.c index fa0904040f..4c87a2d6a5 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c +++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.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. */ @@ -646,6 +646,7 @@ smb_ofile_set_flags( of->f_flags |= flags; mutex_exit(&of->f_mutex); } + /* * smb_ofile_seek * diff --git a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c index ee67413338..25f8d4df4d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_open_andx.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. */ @@ -354,6 +354,7 @@ smb_sdrc_t smb_com_open_andx(smb_request_t *sr) { struct open_param *op = &sr->arg.open; + smb_node_t *node; uint16_t file_attr; smb_attr_t attr; int rc; @@ -385,9 +386,11 @@ smb_com_open_andx(smb_request_t *sr) op->action_taken &= ~SMB_OACT_LOCK; file_attr = op->dattr & FILE_ATTRIBUTE_MASK; - if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { - smb_node_t *node = sr->fid_ofile->f_node; + switch (sr->tid_tree->t_res_type & STYPE_MASK) { + case STYPE_DISKTREE: + case STYPE_PRINTQ: + node = sr->fid_ofile->f_node; if (smb_node_getattr(sr, node, &attr) != 0) { smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, ERRDOS, ERROR_INTERNAL_ERROR); @@ -406,7 +409,9 @@ smb_com_open_andx(smb_request_t *sr) op->devstate, op->action_taken, op->fileid, 0); - } else { + break; + + case STYPE_IPC: rc = smbsr_encode_result(sr, 15, 0, "bb.wwwllwwwwl2.w", 15, @@ -419,6 +424,12 @@ smb_com_open_andx(smb_request_t *sr) op->devstate, op->action_taken, op->fileid, 0); + break; + + default: + smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, + ERRDOS, ERROR_INVALID_FUNCTION); + return (SDRC_ERROR); } return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); @@ -480,7 +491,7 @@ smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa) file_attr = op->dattr & FILE_ATTRIBUTE_MASK; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) op->dsize = 0; (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl", diff --git a/usr/src/uts/common/fs/smbsrv/smb_pathname.c b/usr/src/uts/common/fs/smbsrv/smb_pathname.c index ce03b894ca..216f2fe0a3 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_pathname.c +++ b/usr/src/uts/common/fs/smbsrv/smb_pathname.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. */ @@ -166,7 +166,7 @@ smb_pathname_reduce( vss_root_node = NULL; if (sr && sr->tid_tree) { - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) return (EACCES); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_print.c b/usr/src/uts/common/fs/smbsrv/smb_print.c index 4e21dfdd2b..43074b6882 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_print.c +++ b/usr/src/uts/common/fs/smbsrv/smb_print.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. */ @@ -29,64 +29,54 @@ #include <smbsrv/smb_kproto.h> - /* - * smb_com_open_print_file - * - * This message is sent to create a new printer file which will be deleted - * once it has been closed and printed. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT SetupLength; Length of printer setup data - * USHORT Mode; 0 = Text mode (DOS expands TABs) - * 1 = Graphics mode - * USHORT ByteCount; Count of data bytes; min = 2 - * UCHAR BufferFormat; 0x04 - * STRING IdentifierString[]; Identifier string - * - * Tid in the SMB header must refer to a printer resource type. + * Create a new printer file, which should be deleted automatically once + * it has been closed and printed. * * SetupLength is the number of bytes in the first part of the resulting * print spool file which contains printer-specific control strings. * * Mode can have the following values: - * * 0 Text mode. The server may optionally * expand tabs to a series of spaces. * 1 Graphics mode. No conversion of data * should be done by the server. * - * IdentifierString can be used by the server to provide some sort of per- - * client identifying component to the print file. + * IdentifierString can be used by the server to provide some sort of + * per-client identifying component to the print file. * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes = 0 - * - * Fid is the returned handle which may be used by subsequent write and - * close operations. When the file is finally closed, it will be sent to - * the spooler and printed. - * - * 4.5.1.1 Errors - * - * ERRDOS/ERRnoaccess - * ERRDOS/ERRnofids - * ERRSRV/ERRinvdevice - * ERRSRV/ERRbaduid - * ERRSRV/ERRqfull - * ERRSRV/ERRqtoobig + * When the file is closed, it will be sent to the spooler and printed. */ smb_sdrc_t smb_pre_open_print_file(smb_request_t *sr) { - DTRACE_SMB_1(op__OpenPrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + static uint32_t tmp_id = 10000; + struct open_param *op = &sr->arg.open; + char *path; + char *identifier; + uint16_t setup; + uint16_t mode; + int rc; + + bzero(op, sizeof (sr->arg.open)); + + rc = smbsr_decode_vwv(sr, "ww", &setup, &mode); + if (rc == 0) + rc = smbsr_decode_data(sr, "%S", sr, &identifier); + + atomic_inc_32(&tmp_id); + + path = smb_srm_alloc(sr, MAXPATHLEN); + (void) snprintf(path, MAXPATHLEN, "%s%05u", identifier, tmp_id); + op->fqi.fq_path.pn_path = path; + + op->create_disposition = FILE_OVERWRITE_IF; + op->create_options = FILE_NON_DIRECTORY_FILE; + + DTRACE_SMB_2(op__OpenPrintFile__start, smb_request_t *, sr, + struct open_param *, op); + + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void @@ -95,46 +85,42 @@ smb_post_open_print_file(smb_request_t *sr) DTRACE_SMB_1(op__OpenPrintFile__done, smb_request_t *, sr); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_open_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); -} + int rc; + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + + if (smb_common_create(sr) != NT_STATUS_SUCCESS) + return (SDRC_ERROR); + + rc = smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); +} /* - * smb_com_close_print_file - * - * - * This message invalidates the specified file handle and queues the file - * for printing. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes = 0 - * - * Fid refers to a file previously created with SMB_COM_OPEN_PRINT_FILE. + * Close the specified file handle and queue the file for printing. + * The fid refers to a file previously created as a print spool file. * On successful completion of this request, the file is queued for * printing by the server. * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 0 - * USHORT ByteCount; Count of data bytes = 0 - * - * Servers which negotiate dialects of LANMAN1.0 and newer allow all the - * other types of Fid closing requests to invalidate the Fid and begin - * spooling. + * Servers that negotiate LANMAN1.0 or later allow all the the fid + * to be closed and printed via any close request. */ smb_sdrc_t smb_pre_close_print_file(smb_request_t *sr) { + int rc; + + rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid); + DTRACE_SMB_1(op__ClosePrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void @@ -143,81 +129,21 @@ smb_post_close_print_file(smb_request_t *sr) DTRACE_SMB_1(op__ClosePrintFile__done, smb_request_t *, sr); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_close_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); -} + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + return (smb_com_close(sr)); +} /* - * smb_com_get_print_queue - * - * This message obtains a list of the elements currently in the print queue - * on the server. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT MaxCount; Max number of entries to return - * USHORT StartIndex; First queue entry to return - * USHORT ByteCount; Count of data bytes = 0 - * - * StartIndex specifies the first entry in the queue to return. - * - * MaxCount specifies the maximum number of entries to return, this may be - * a positive or negative number. A positive number requests a forward - * search, a negative number indicates a backward search. - * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT Count; Number of entries returned - * USHORT RestartIndex; Index of entry after last - * returned - * USHORT ByteCount; Count of data bytes; min = 3 - * UCHAR BufferFormat; 0x01 -- Data block - * USHORT DataLength; Length of data - * UCHAR Data[]; Queue elements - * - * Count indicates how many entries were actually returned. RestartIndex - * is the index of the entry following the last entry returned; it may be - * used as the StartIndex in a subsequent request to resume the queue - * listing. - * - * The format of each returned queue element is: - * - * Queue Element Member Description - * ================================ =================================== - * - * SMB_DATE FileDate; Date file was queued - * SMB_TIME FileTime; Time file was queued - * UCHAR Status; Entry status. One of: - * 01 = held or stopped - * 02 = printing - * 03 = awaiting print - * 04 = in intercept - * 05 = file had error - * 06 = printer error - * 07-FF = reserved - * USHORT SpoolFileNumber; Assigned by the spooler - * ULONG SpoolFileSize; Number of bytes in spool file - * UCHAR Reserved; - * UCHAR SpoolFileName[16]; Client which created the spool file - * - * SMB_COM_GET_PRINT_QUEUE will return less than the requested number of - * elements only when the top or end of the queue is encountered. - * - * Support for this SMB is server optional. In particular, no current - * Microsoft client software issues this request. - * - * 4.5.2.1 Errors - * - * ERRHRD/ERRnotready - * ERRHRD/ERRerror - * ERRSRV/ERRbaduid + * Get a list of print queue entries on the server. Support for + * this request is optional (not required for Windows clients). */ smb_sdrc_t smb_pre_get_print_queue(smb_request_t *sr) @@ -246,58 +172,85 @@ smb_com_get_print_queue(smb_request_t *sr) return (SDRC_SUCCESS); } - /* - * smb_com_write_print_file - * - * This message is sent to write bytes into a print spool file. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes; min = 4 - * UCHAR BufferFormat; 0x01 -- Data block - * USHORT DataLength; Length of data - * UCHAR Data[]; Data - * - * Fid indicates the print spool file to be written, it must refer to a - * print spool file. - * - * ByteCount specifies the number of bytes to be written, and must be less - * than MaxBufferSize for the Tid specified. - * - * Data contains the bytes to append to the print spool file. The first - * SetupLength bytes in the resulting print spool file contain printer - * setup data. SetupLength is specified in the SMB_COM_OPEN_PRINT_FILE SMB - * request. - * - * Server Response Description - * ================================== ================================= + * Write (append) data to a print spool file. The fid must refer to + * a print spool file. * - * UCHAR WordCount; Count of parameter words = 0 - * USHORT ByteCount; Count of data bytes = 0 - * - * Servers which negotiate a protocol dialect of LANMAN1.0 or later also - * support the application of normal write requests to print spool files. + * The first SetupLength bytes (see SMB_COM_OPEN_PRINT_FILE) in the + * print spool file contain printer setup data. * + * Servers that negotiate LANMAN1.0 or later also support the use of + * normal write requests with print spool files. */ smb_sdrc_t smb_pre_write_print_file(smb_request_t *sr) { + smb_rw_param_t *param; + int rc; + + param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP); + sr->arg.rw = param; + param->rw_magic = SMB_RW_MAGIC; + + rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid); + DTRACE_SMB_1(op__WritePrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void smb_post_write_print_file(smb_request_t *sr) { DTRACE_SMB_1(op__WritePrintFile__done, smb_request_t *, sr); + + kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_write_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); + smb_rw_param_t *param = sr->arg.rw; + smb_node_t *node; + smb_attr_t attr; + int rc; + + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) { + smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); + return (SDRC_ERROR); + } + + node = sr->fid_ofile->f_node; + sr->user_cr = smb_ofile_getcred(sr->fid_ofile); + + if (smb_node_getattr(sr, node, &attr) != 0) { + smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, + ERRDOS, ERROR_INTERNAL_ERROR); + return (SDRC_ERROR); + } + + if ((smbsr_decode_data(sr, "D", ¶m->rw_vdb)) != 0) { + smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, + ERRDOS, ERROR_INVALID_PARAMETER); + return (SDRC_ERROR); + } + + param->rw_count = param->rw_vdb.vdb_len; + param->rw_offset = attr.sa_vattr.va_size; + param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; + + if ((rc = smb_common_write(sr, param)) != 0) { + if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT) + smbsr_errno(sr, rc); + return (SDRC_ERROR); + } + + rc = smbsr_encode_empty_result(sr); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c index 64897deb50..6585716e33 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.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. */ @@ -123,7 +123,7 @@ smb_com_trans2_query_path_information(smb_request_t *sr, smb_xa_t *xa) uint16_t infolev; char *path; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, ERRDOS, ERROR_INVALID_FUNCTION); return (SDRC_ERROR); @@ -168,7 +168,7 @@ smb_com_query_information(smb_request_t *sr) char *path = sr->arg.dirop.fqi.fq_path.pn_path; uint16_t infolev = SMB_QUERY_INFORMATION; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERROR_ACCESS_DENIED); return (SDRC_ERROR); diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c index 3053fa3a67..4fcfdd6b40 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c +++ b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.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. */ @@ -88,7 +88,7 @@ smb_com_query_information_disk(smb_request_t *sr) unsigned short blocks_per_unit, bytes_per_block; unsigned short total_units, free_units; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess); return (SDRC_ERROR); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c index e79a595b15..ea6344ce3e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_read.c +++ b/usr/src/uts/common/fs/smbsrv/smb_read.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. */ @@ -509,6 +509,7 @@ smb_common_read(smb_request_t *sr, smb_rw_param_t *param) vdb->vdb_uio.uio_resid = param->rw_count; vdb->vdb_uio.uio_loffset = (offset_t)param->rw_offset; vdb->vdb_uio.uio_segflg = UIO_SYSSPACE; + vdb->vdb_uio.uio_extflg = UIO_COPY_DEFAULT; switch (sr->tid_tree->t_res_type & STYPE_MASK) { case STYPE_DISKTREE: diff --git a/usr/src/uts/common/fs/smbsrv/smb_sd.c b/usr/src/uts/common/fs/smbsrv/smb_sd.c index b8d7fd3b7a..906639c155 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_sd.c +++ b/usr/src/uts/common/fs/smbsrv/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. */ @@ -325,8 +325,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); @@ -348,8 +347,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/uts/common/fs/smbsrv/smb_set_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c index 2c98d81c5e..081a67407e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.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. */ @@ -115,7 +115,7 @@ smb_com_trans2_set_path_information(smb_request_t *sr, smb_xa_t *xa) uint16_t infolev; char *path; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, ERRDOS, ERROR_INVALID_FUNCTION); return (SDRC_ERROR); @@ -153,7 +153,7 @@ smb_com_set_information(smb_request_t *sr) uint16_t infolev = SMB_SET_INFORMATION; char *path; - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERROR_ACCESS_DENIED); return (SDRC_ERROR); @@ -226,7 +226,7 @@ smb_set_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev) return (-1); } - if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) return (0); smbsr_lookup_file(sr); diff --git a/usr/src/uts/common/fs/smbsrv/smb_util.c b/usr/src/uts/common/fs/smbsrv/smb_util.c index 2d3693273b..3931e2cf41 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_util.c +++ b/usr/src/uts/common/fs/smbsrv/smb_util.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. */ @@ -1401,9 +1401,25 @@ smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim, &sim->sim_stat); break; + case SMB_IDMAP_OWNERAT: + /* Current Owner S-1-5-32-766 */ + sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR; + sim->sim_rid = SECURITY_CURRENT_OWNER_RID; + sim->sim_stat = IDMAP_SUCCESS; + idm_stat = IDMAP_SUCCESS; + break; + + case SMB_IDMAP_GROUPAT: + /* Current Group S-1-5-32-767 */ + sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR; + sim->sim_rid = SECURITY_CURRENT_GROUP_RID; + sim->sim_stat = IDMAP_SUCCESS; + idm_stat = IDMAP_SUCCESS; + break; + case SMB_IDMAP_EVERYONE: /* Everyone S-1-1-0 */ - sim->sim_domsid = "S-1-1"; + sim->sim_domsid = NT_WORLD_AUTH_SIDSTR; sim->sim_rid = 0; sim->sim_stat = IDMAP_SUCCESS; idm_stat = IDMAP_SUCCESS; diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c index 93782f0b6d..24a08b006f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vops.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. */ @@ -923,6 +923,7 @@ smb_vop_readdir(vnode_t *vp, uint32_t offset, auio.uio_iovcnt = 1; auio.uio_loffset = (uint64_t)offset; auio.uio_segflg = UIO_SYSSPACE; + auio.uio_extflg = UIO_COPY_DEFAULT; auio.uio_resid = *count; auio.uio_fmode = 0; diff --git a/usr/src/uts/common/fs/smbsrv/smb_write.c b/usr/src/uts/common/fs/smbsrv/smb_write.c index a07e555494..2b9d5ffb3c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_write.c +++ b/usr/src/uts/common/fs/smbsrv/smb_write.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. */ @@ -29,9 +29,6 @@ #include <smbsrv/netbios.h> -#define SMB_WRMODE_WRITE_THRU 0x0001 -#define SMB_WRMODE_IS_STABLE(M) ((M) & SMB_WRMODE_WRITE_THRU) - /* * The limit in bytes that the marshalling will grow the buffer * chain to accomodate incoming data on SmbWriteX requests. @@ -40,7 +37,6 @@ */ #define SMB_WRITEX_MAX 102400 -static int smb_write_common(smb_request_t *, smb_rw_param_t *); static int smb_write_truncate(smb_request_t *, smb_rw_param_t *); @@ -114,7 +110,7 @@ smb_com_write(smb_request_t *sr) param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; - rc = smb_write_common(sr, param); + rc = smb_common_write(sr, param); } if (rc != 0) { @@ -209,7 +205,7 @@ smb_com_write_and_close(smb_request_t *sr) param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; - rc = smb_write_common(sr, param); + rc = smb_common_write(sr, param); } if (rc != 0) { @@ -311,7 +307,7 @@ smb_com_write_and_unlock(smb_request_t *sr) param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; - if ((rc = smb_write_common(sr, param)) != 0) { + if ((rc = smb_common_write(sr, param)) != 0) { if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT) smbsr_errno(sr, rc); return (SDRC_ERROR); @@ -417,7 +413,7 @@ smb_com_write_andx(smb_request_t *sr) sr->user_cr = smb_ofile_getcred(sr->fid_ofile); if (SMB_WRMODE_IS_STABLE(param->rw_mode) && - STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) { + STYPE_ISIPC(sr->tid_tree->t_res_type)) { smbsr_error(sr, 0, ERRSRV, ERRaccess); return (SDRC_ERROR); } @@ -435,7 +431,7 @@ smb_com_write_andx(smb_request_t *sr) param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; if (param->rw_count != 0) { - if ((rc = smb_write_common(sr, param)) != 0) { + if ((rc = smb_common_write(sr, param)) != 0) { if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT) smbsr_errno(sr, rc); @@ -457,8 +453,8 @@ smb_com_write_andx(smb_request_t *sr) * * Returns errno values. */ -static int -smb_write_common(smb_request_t *sr, smb_rw_param_t *param) +int +smb_common_write(smb_request_t *sr, smb_rw_param_t *param) { smb_ofile_t *ofile = sr->fid_ofile; smb_node_t *node; @@ -468,6 +464,7 @@ smb_write_common(smb_request_t *sr, smb_rw_param_t *param) switch (sr->tid_tree->t_res_type & STYPE_MASK) { case STYPE_DISKTREE: + case STYPE_PRINTQ: node = ofile->f_node; if (!smb_node_is_dir(node)) { @@ -537,7 +534,7 @@ smb_write_truncate(smb_request_t *sr, smb_rw_param_t *param) uint32_t status; int rc; - if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) return (0); mutex_enter(&node->n_mutex); diff --git a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c index 446b25bb23..3c503efbf9 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c +++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.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. */ @@ -188,16 +188,42 @@ extern uint32_t smb_keep_alive; -static int smb_write_raw_helper(smb_request_t *, struct uio *, int, - offset_t *, uint32_t *); static int smb_transfer_write_raw_data(smb_request_t *, uint16_t); -#define WR_MODE_WR_THRU 1 - smb_sdrc_t smb_pre_write_raw(smb_request_t *sr) { - int rc = 0; + smb_rw_param_t *param; + uint32_t off_low; + uint32_t off_high; + uint32_t timeout; + uint16_t datalen; + uint16_t total; + int rc; + + param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP); + sr->arg.rw = param; + param->rw_magic = SMB_RW_MAGIC; + + if (sr->smb_wct == 12) { + off_high = 0; + rc = smbsr_decode_vwv(sr, "ww2.llw4.ww", &sr->smb_fid, &total, + &off_low, &timeout, ¶m->rw_mode, &datalen, + ¶m->rw_dsoff); + + param->rw_offset = (uint64_t)off_low; + param->rw_dsoff -= 59; + } else { + rc = smbsr_decode_vwv(sr, "ww2.llw4.wwl", &sr->smb_fid, &total, + &off_low, &timeout, ¶m->rw_mode, &datalen, + ¶m->rw_dsoff, &off_high); + + param->rw_offset = ((uint64_t)off_high << 32) | off_low; + param->rw_dsoff -= 63; + } + + param->rw_count = (uint32_t)datalen; + param->rw_total = (uint32_t)total; DTRACE_SMB_2(op__WriteRaw__start, smb_request_t *, sr, smb_rw_param_t *, sr->arg.rw); @@ -214,48 +240,26 @@ smb_post_write_raw(smb_request_t *sr) smb_rw_param_t *, sr->arg.rw); smb_rwx_rwexit(&sr->session->s_lock); + kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t smb_com_write_raw(struct smb_request *sr) { + smb_rw_param_t *param = sr->arg.rw; int rc = 0; int session_send_rc = 0; - unsigned short addl_xfer_count; - unsigned short count; - unsigned short write_mode, data_offset, data_length; - offset_t off; - uint32_t off_low, off_high, timeout; - uint32_t lcount = 0; - uint32_t addl_lcount = 0; - struct uio uio; - iovec_t iovec; - int stability; + uint16_t addl_xfer_count; + offset_t addl_xfer_offset; struct mbuf_chain reply; - smb_node_t *fnode; smb_error_t err; + int32_t chain_offset; if (sr->session->s_state != SMB_SESSION_STATE_WRITE_RAW_ACTIVE) return (SDRC_DROP_VC); - if (sr->smb_wct == 12) { - off_high = 0; - rc = smbsr_decode_vwv(sr, "ww2.llw4.ww", &sr->smb_fid, &count, - &off_low, &timeout, &write_mode, &data_length, - &data_offset); - data_offset -= 59; - } else { - rc = smbsr_decode_vwv(sr, "ww2.llw4.wwl", &sr->smb_fid, &count, - &off_low, &timeout, &write_mode, &data_length, - &data_offset, &off_high); - data_offset -= 63; - } - - if (rc != 0) - return (SDRC_ERROR); - - off = ((offset_t)off_high << 32) | off_low; - addl_xfer_count = count - data_length; + addl_xfer_count = param->rw_total - param->rw_count; + addl_xfer_offset = param->rw_count; smbsr_lookup_file(sr); if (sr->fid_ofile == NULL) { @@ -265,45 +269,26 @@ smb_com_write_raw(struct smb_request *sr) sr->user_cr = smb_ofile_getcred(sr->fid_ofile); - fnode = sr->fid_ofile->f_node; - stability = ((write_mode & WR_MODE_WR_THRU) || - (fnode->flags & NODE_FLAGS_WRITE_THROUGH)) ? FSYNC : 0; - - if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { - /* - * See comments in smb_write.c - */ - if (!smb_node_is_dir(fnode)) { - rc = smb_lock_range_access(sr, fnode, off, - count, B_TRUE); - if (rc != NT_STATUS_SUCCESS) { - smbsr_error(sr, rc, ERRSRV, ERRaccess); - return (SDRC_ERROR); - } - } - } - /* * Make sure any raw write data that is supposed to be * contained in this SMB is actually present. */ - if (sr->smb_data.chain_offset + data_offset + data_length > - sr->smb_data.max_bytes) { + chain_offset = sr->smb_data.chain_offset + param->rw_dsoff + + param->rw_count; + if (chain_offset > sr->smb_data.max_bytes) { /* Error handling code will wake up the session daemon */ return (SDRC_ERROR); } - /* - * Init uio (resid will get filled in later) - */ - uio.uio_iov = &iovec; - uio.uio_iovcnt = 1; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_loffset = off; + param->rw_vdb.vdb_uio.uio_iov = ¶m->rw_vdb.vdb_iovec[0]; + param->rw_vdb.vdb_uio.uio_iovcnt = 1; + param->rw_vdb.vdb_uio.uio_segflg = UIO_SYSSPACE; + param->rw_vdb.vdb_uio.uio_extflg = UIO_COPY_DEFAULT; + param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; /* - * Send response if there is additional data to transfer. This - * will prompt the client to send the remaining data. + * Send response if there is additional data to transfer. + * This will prompt the client to send the remaining data. */ if (addl_xfer_count != 0) { MBC_INIT(&reply, MLEN); @@ -327,39 +312,24 @@ smb_com_write_raw(struct smb_request *sr) session_send_rc = smb_session_send(sr->session, 0, &reply); /* - * If the session response failed we're not going to - * return an error just yet -- we can still write the - * data we received along with the SMB even if the - * response failed. If it failed, we need to force the - * stability level to "write-through". + * If the response failed, force write-through and + * complete the write before dealing with the error. */ - stability = (session_send_rc == 0) ? stability : FSYNC; + if (session_send_rc != 0) + param->rw_mode = SMB_WRMODE_WRITE_THRU; } /* * While the response is in flight (and the data begins to arrive) - * write out the first data segment. Start by setting up the - * iovec list for the first transfer. + * write out the first data segment. */ - iovec.iov_base = sr->smb_data.chain->m_data + - sr->smb_data.chain_offset + data_offset; - iovec.iov_len = data_length; - uio.uio_resid = data_length; + param->rw_vdb.vdb_iovec[0].iov_base = sr->smb_data.chain->m_data + + sr->smb_data.chain_offset + param->rw_dsoff; + param->rw_vdb.vdb_iovec[0].iov_len = param->rw_count; + param->rw_vdb.vdb_uio.uio_resid = param->rw_count; - /* - * smb_write_raw_helper will call smb_opipe_write or - * smb_fsop_write as appropriate, and update the other f_node fields. - * It's possible that data_length may be 0 for this transfer but - * we still want to process it since it will update the file state - * (seek position, file size (possibly), etc). - */ - rc = smb_write_raw_helper(sr, &uio, stability, &off, &lcount); + rc = smb_common_write(sr, param); - /* - * If our initial session response failed then we're done. Return - * failure. The client will know we wrote some of the data because - * of the transfer count (count - lcount) in the response. - */ if (session_send_rc != 0) { sr->smb_rcls = ERRSRV; sr->smb_err = ERRusestd; @@ -376,19 +346,14 @@ smb_com_write_raw(struct smb_request *sr) * is read successfully then the buffer (sr->sr_raw_data_buf) * will need to be freed after the data is written. */ - if (smb_transfer_write_raw_data(sr, addl_xfer_count) != 0) { - /* - * Raw data transfer failed - */ + param->rw_offset += addl_xfer_offset; + + if (smb_transfer_write_raw_data(sr, addl_xfer_count) != 0) goto write_raw_transfer_failed; - } - /* - * Fill in next iov entry - */ - iovec.iov_base = sr->sr_raw_data_buf; - iovec.iov_len = addl_xfer_count; - uio.uio_resid = addl_xfer_count; + param->rw_vdb.vdb_iovec[0].iov_base = sr->sr_raw_data_buf; + param->rw_vdb.vdb_iovec[0].iov_len = addl_xfer_count; + param->rw_vdb.vdb_uio.uio_resid = addl_xfer_count; } /* @@ -405,30 +370,24 @@ smb_com_write_raw(struct smb_request *sr) * want to drop the connection and we need to read through * to the next SMB). */ - if ((rc != 0) || (lcount != data_length)) { + if (rc != 0) goto notify_write_raw_complete; - } /* * Write any additional data */ - if (addl_xfer_count) { - rc = smb_write_raw_helper(sr, &uio, stability, &off, - &addl_lcount); - } + if (addl_xfer_count) + rc = smb_common_write(sr, param); /* - * If we were called in "Write-behind" mode ((write_mode & 1) == 0) - * and the transfer was successful then we don't need to send - * any further response. If we were called in "Write-Through" mode - * ((write_mode & 1) == 1) or if the transfer failed we need to - * send a completion notification. The "count" value will indicate - * whether the transfer was successful. + * If we were called in "Write-behind" mode and the transfer was + * successful then we don't need to send any further response. + * If we were called in "Write-Through" mode or if the transfer + * failed we need to send a completion notification. The "count" + * value will indicate whether the transfer was successful. */ - if ((rc != 0) || (write_mode & WR_MODE_WR_THRU) || - (lcount + addl_lcount != count)) { + if ((rc != 0) || SMB_WRMODE_IS_STABLE(param->rw_mode)) goto notify_write_raw_complete; - } /* * Free raw write buffer (allocated in smb_transfer_write_raw_data) @@ -440,8 +399,7 @@ smb_com_write_raw(struct smb_request *sr) write_raw_transfer_failed: /* - * Raw data transfer failed, wake up session - * daemon + * Raw data transfer failed, wake up session daemon */ sr->session->s_write_raw_status = 20; sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED; @@ -458,59 +416,15 @@ notify_write_raw_complete: /* * Free raw write buffer if present (from smb_transfer_write_raw_data) */ - if (sr->sr_raw_data_buf != NULL) { + if (sr->sr_raw_data_buf != NULL) kmem_free(sr->sr_raw_data_buf, sr->sr_raw_data_length); - } - /* Write complete notification */ + sr->first_smb_com = SMB_COM_WRITE_COMPLETE; rc = smbsr_encode_result(sr, 1, 0, "bww", 1, - count - (lcount + addl_lcount), 0); + param->rw_total - param->rw_count, 0); return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } - - -/* - * smb_write_raw_helper - * - * This function will call smb_opipe_write or smb_fsop_write - * as appropriate, and update the other f_node fields. - * It's possible that data_length may be 0 for this transfer but - * we still want process it since it will update the file state - * (seek position, file size (possibly), etc). - * - * Returns 0 for success, non-zero for failure - */ -static int -smb_write_raw_helper(struct smb_request *sr, struct uio *uiop, - int stability, offset_t *offp, uint32_t *lcountp) -{ - smb_node_t *fnode; - int rc = 0; - - if (STYPE_ISIPC(sr->tid_tree->t_res_type)) { - *lcountp = uiop->uio_resid; - - if ((rc = smb_opipe_write(sr, uiop)) != 0) - *lcountp = 0; - } else { - fnode = sr->fid_ofile->f_node; - rc = smb_fsop_write(sr, sr->user_cr, fnode, - uiop, lcountp, stability); - - if (rc == 0) - smb_ofile_set_write_time_pending(sr->fid_ofile); - } - - *offp += *lcountp; - mutex_enter(&sr->fid_ofile->f_mutex); - sr->fid_ofile->f_seek_pos = *offp; - mutex_exit(&sr->fid_ofile->f_mutex); - - return (rc); -} - - /* * smb_handle_write_raw * diff --git a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl index b26393bcf7..e08b06e626 100644 --- a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl +++ b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl @@ -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. */ @@ -290,6 +290,19 @@ struct samr_short_blob { WORD *buf; }; +#define DOMAIN_PASSWORD_COMPLEX 0x00000001 +#define DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002 +#define DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004 +#define DOMAIN_LOCKOUT_ADMINS 0x00000008 +#define DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010 +#define DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020 + +struct samr_password_info { + WORD min_length; + DWORD properties; +}; +typedef struct samr_password_info samr_password_info_t; + /* * There is some sort of logon bitmap structure in here, which I * think is a varying and conformant array, i.e. @@ -586,6 +599,17 @@ struct samr_QueryDomainInfo { OUT DWORD status; }; +/* + * Identical to SAMR_OPNUM_QueryDomainInfo. + */ +OPERATION(SAMR_OPNUM_QueryInfoDomain2) +struct samr_QueryInfoDomain2 { + IN samr_handle_t domain_handle; + IN WORD info_level; + OUT struct samr_QueryDomainInfoRes *info; + OUT DWORD status; +}; + #define SAMR_QUERY_ALIAS_INFO_1 1 #define SAMR_QUERY_ALIAS_INFO_3 3 @@ -1105,26 +1129,14 @@ struct samr_StoreGroupInfo { /* *********************************************************************** - * Request 0x2c is a user request. The only parameter is a user handle. - * The response is 12 bytes of the form: - * unknown: 00 00 BB 01 (443) - * unknown: 00 00 00 00 - * status: 00 00 00 00 - * RPC book lists this as GetUsrDomPwInfo. + * GetUserDomainPasswordInformation *********************************************************************** */ -struct samr_UserPwInfo { - WORD unknown1; - WORD unknown2; - DWORD unknown3; -}; - - OPERATION(SAMR_OPNUM_GetUserPwInfo) struct samr_GetUserPwInfo { - IN samr_handle_t user_handle; - OUT struct samr_UserPwInfo pw_info; - OUT DWORD status; + IN samr_handle_t user_handle; + OUT REFERENCE samr_password_info_t *pwinfo; + OUT DWORD status; }; @@ -1186,11 +1198,9 @@ struct samr_ChangeUserPasswd { */ OPERATION(SAMR_OPNUM_GetDomainPwInfo) struct samr_GetDomainPwInfo { - IN LPTSTR servername; - OUT WORD unknown0; - OUT WORD unknown1; - OUT WORD unknown2; - OUT DWORD status; + IN DWORD unused; + OUT REFERENCE samr_password_info_t *pwinfo; + OUT DWORD status; }; @@ -1386,6 +1396,8 @@ union samr_interface { struct samr_OpenDomain OpenDomain; CASE(SAMR_OPNUM_QueryDomainInfo) struct samr_QueryDomainInfo QueryDomainInfo; + CASE(SAMR_OPNUM_QueryInfoDomain2) + struct samr_QueryInfoDomain2 QueryInfoDomain2; CASE(SAMR_OPNUM_LookupNames) struct samr_LookupNames LookupNames; CASE(SAMR_OPNUM_OpenUser) diff --git a/usr/src/uts/common/smbsrv/ndl/winreg.ndl b/usr/src/uts/common/smbsrv/ndl/winreg.ndl index bb273ca328..d09cc32ed2 100644 --- a/usr/src/uts/common/smbsrv/ndl/winreg.ndl +++ b/usr/src/uts/common/smbsrv/ndl/winreg.ndl @@ -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. */ @@ -151,9 +151,9 @@ struct file_time { typedef struct file_time file_time_t; struct winreg_secdesc { - DWORD sd_length_is; - SIZE_IS(sd_length_is) - BYTE value[ANY_SIZE_ARRAY]; + struct winreg_value *sd_buf; + DWORD sd_len; + DWORD sd_size; }; OPERATION(WINREG_OPNUM_OpenHKCR) @@ -279,15 +279,10 @@ struct winreg_FlushKey { OPERATION(WINREG_OPNUM_GetKeySec) struct winreg_GetKeySec { - IN winreg_handle_t handle; - IN DWORD sec_info; -/* - OUT struct winreg_secdesc sd; -*/ - OUT DWORD sd_length_is; - OUT DWORD sd_size_is; - OUT DWORD sd_array; - OUT DWORD status; + IN winreg_handle_t handle; + IN DWORD sec_info; + OUT REFERENCE struct winreg_secdesc *sd; + OUT DWORD status; }; OPERATION(WINREG_OPNUM_NotifyChange) diff --git a/usr/src/uts/common/smbsrv/ntifs.h b/usr/src/uts/common/smbsrv/ntifs.h index cc1829fc29..14eca1c735 100644 --- a/usr/src/uts/common/smbsrv/ntifs.h +++ b/usr/src/uts/common/smbsrv/ntifs.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. */ @@ -578,7 +578,7 @@ void smb_fssd_term(smb_fssd_t *); void smb_acl_sort(smb_acl_t *); void smb_acl_free(smb_acl_t *); smb_acl_t *smb_acl_alloc(uint8_t, uint16_t, uint16_t); -smb_acl_t *smb_acl_from_zfs(acl_t *, uid_t, gid_t); +smb_acl_t *smb_acl_from_zfs(acl_t *); uint32_t smb_acl_to_zfs(smb_acl_t *, uint32_t, int, acl_t **); uint16_t smb_acl_len(smb_acl_t *); boolean_t smb_acl_isvalid(smb_acl_t *, int); diff --git a/usr/src/uts/common/smbsrv/smb_idmap.h b/usr/src/uts/common/smbsrv/smb_idmap.h index 013dfa4e04..d69af220eb 100644 --- a/usr/src/uts/common/smbsrv/smb_idmap.h +++ b/usr/src/uts/common/smbsrv/smb_idmap.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SMB_IDMAP_H #define _SMB_IDMAP_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef _KERNEL #include <sys/kidmap.h> #else @@ -53,7 +51,9 @@ extern "C" { #define SMB_IDMAP_UNKNOWN -1 #define SMB_IDMAP_GROUP 0 #define SMB_IDMAP_USER 1 -#define SMB_IDMAP_EVERYONE 2 +#define SMB_IDMAP_OWNERAT 2 +#define SMB_IDMAP_GROUPAT 3 +#define SMB_IDMAP_EVERYONE 4 #define SMB_IDMAP_SID2ID 0x0001 #define SMB_IDMAP_ID2SID 0x0002 diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h index a3a0799449..5ec7b6285d 100644 --- a/usr/src/uts/common/smbsrv/smb_kproto.h +++ b/usr/src/uts/common/smbsrv/smb_kproto.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. */ @@ -63,12 +63,26 @@ int fd_dealloc(int); off_t lseek(int fildes, off_t offset, int whence); int arpioctl(int cmd, void *data); -/* Why? uint32_t inet_addr(char *str); */ int microtime(timestruc_t *tvp); int clock_get_uptime(void); /* - * SMB request handers called from the dispatcher. + * SMB request handers called from the dispatcher. Each SMB request + * is handled in three phases: pre, com (command) and post. + * + * The pre-handler is primarily to set things up for the DTrace start + * probe. Typically, the SMB request is unmarshalled so that request + * specific context can be traced. This is also a useful place to + * allocate memory that will be used throughout the processing of the + * command. + * + * The com-handler performs the requested operation: request validation, + * bulk (write) incoming data decode, implementation of the appropriate + * algorithm and transmission of a response (as appropriate). + * + * The post-handler is always called, regardless of success or failure + * of the pre or com functions, to trigger the DTrace done probe and + * deallocate memory allocated in the pre-handler. */ #define SMB_SDT_OPS(NAME) \ smb_pre_##NAME, \ @@ -233,7 +247,9 @@ int smb_ascii_or_unicode_null_len(smb_request_t *); int smb_search(smb_request_t *); +uint32_t smb_common_create(smb_request_t *); uint32_t smb_common_open(smb_request_t *); +int smb_common_write(smb_request_t *, smb_rw_param_t *); void smb_pathname_init(smb_request_t *, smb_pathname_t *, char *); boolean_t smb_pathname_validate(smb_request_t *, smb_pathname_t *); diff --git a/usr/src/uts/common/smbsrv/smb_ktypes.h b/usr/src/uts/common/smbsrv/smb_ktypes.h index fd0feee85b..906c184f78 100644 --- a/usr/src/uts/common/smbsrv/smb_ktypes.h +++ b/usr/src/uts/common/smbsrv/smb_ktypes.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. */ @@ -1144,6 +1144,9 @@ typedef struct vardata_block { struct iovec vdb_iovec[MAX_IOVEC]; } smb_vdb_t; +#define SMB_WRMODE_WRITE_THRU 0x0001 +#define SMB_WRMODE_IS_STABLE(M) ((M) & SMB_WRMODE_WRITE_THRU) + #define SMB_RW_MAGIC 0x52445257 /* 'RDRW' */ typedef struct smb_rw_param { @@ -1152,8 +1155,9 @@ typedef struct smb_rw_param { uint64_t rw_offset; uint32_t rw_last_write; uint16_t rw_mode; - uint32_t rw_count; + uint32_t rw_count; /* bytes in this request */ uint16_t rw_mincnt; + uint32_t rw_total; /* total bytes (write-raw) */ uint16_t rw_dsoff; /* SMB data offset */ uint8_t rw_andx; /* SMB secondary andx command */ } smb_rw_param_t; diff --git a/usr/src/uts/common/smbsrv/smb_sid.h b/usr/src/uts/common/smbsrv/smb_sid.h index c9f5479bd1..fe7d75073d 100644 --- a/usr/src/uts/common/smbsrv/smb_sid.h +++ b/usr/src/uts/common/smbsrv/smb_sid.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. */ @@ -46,12 +46,14 @@ extern "C" { * Predefined global group RIDs. */ #define DOMAIN_GROUP_RID_ADMINS (0x00000200L) /* 512 */ -#define DOMAIN_GROUP_RID_USERS (0x00000201L) -#define DOMAIN_GROUP_RID_GUESTS (0x00000202L) -#define DOMAIN_GROUP_RID_COMPUTERS (0x00000203L) -#define DOMAIN_GROUP_RID_CONTROLLERS (0x00000204L) -#define DOMAIN_GROUP_RID_CERT_ADMINS (0x00000205L) -#define DOMAIN_GROUP_RID_SCHEMA_ADMINS (0x00000206L) +#define DOMAIN_GROUP_RID_USERS (0x00000201L) /* 513 */ +#define DOMAIN_GROUP_RID_GUESTS (0x00000202L) /* 514 */ +#define DOMAIN_GROUP_RID_COMPUTERS (0x00000203L) /* 515 */ +#define DOMAIN_GROUP_RID_CONTROLLERS (0x00000204L) /* 516 */ +#define DOMAIN_GROUP_RID_CERT_ADMINS (0x00000205L) /* 517 */ +#define DOMAIN_GROUP_RID_SCHEMA_ADMINS (0x00000206L) /* 518 */ +#define DOMAIN_GROUP_RID_EP_ADMINS (0x00000207L) /* 519 */ +#define DOMAIN_GROUP_RID_GP_CREATOR (0x00000208L) /* 520 */ /* @@ -71,19 +73,26 @@ extern "C" { /* * Universal and NT well-known SIDs */ +#define NT_NULL_AUTH_SIDSTR "S-1-0" #define NT_NULL_SIDSTR "S-1-0-0" +#define NT_WORLD_AUTH_SIDSTR "S-1-1" #define NT_WORLD_SIDSTR "S-1-1-0" +#define NT_LOCAL_AUTH_SIDSTR "S-1-2" #define NT_LOCAL_SIDSTR "S-1-2-0" +#define NT_CREATOR_AUTH_SIDSTR "S-1-3" #define NT_CREATOR_OWNER_ID_SIDSTR "S-1-3-0" #define NT_CREATOR_GROUP_ID_SIDSTR "S-1-3-1" #define NT_CREATOR_OWNER_SERVER_ID_SIDSTR "S-1-3-2" #define NT_CREATOR_GROUP_SERVER_ID_SIDSTR "S-1-3-3" +#define NT_OWNER_RIGHTS_SIDSTR "S-1-3-4" +#define NT_GROUP_RIGHTS_SIDSTR "S-1-3-5" #define NT_NON_UNIQUE_IDS_SIDSTR "S-1-4" #define NT_AUTHORITY_SIDSTR "S-1-5" #define NT_DIALUP_SIDSTR "S-1-5-1" #define NT_NETWORK_SIDSTR "S-1-5-2" #define NT_BATCH_SIDSTR "S-1-5-3" #define NT_INTERACTIVE_SIDSTR "S-1-5-4" +#define NT_LOGON_SESSION_SIDSTR "S-1-5-5" #define NT_SERVICE_SIDSTR "S-1-5-6" #define NT_ANONYMOUS_LOGON_SIDSTR "S-1-5-7" #define NT_PROXY_SIDSTR "S-1-5-8" @@ -91,9 +100,12 @@ extern "C" { #define NT_SELF_SIDSTR "S-1-5-10" #define NT_AUTHENTICATED_USER_SIDSTR "S-1-5-11" #define NT_RESTRICTED_CODE_SIDSTR "S-1-5-12" +#define NT_TERMINAL_SERVER_SIDSTR "S-1-5-13" #define NT_LOCAL_SYSTEM_SIDSTR "S-1-5-18" #define NT_NON_UNIQUE_SIDSTR "S-1-5-21" #define NT_BUILTIN_DOMAIN_SIDSTR "S-1-5-32" +#define NT_BUILTIN_CURRENT_OWNER_SIDSTR "S-1-5-32-766" +#define NT_BUILTIN_CURRENT_GROUP_SIDSTR "S-1-5-32-767" /* @@ -140,6 +152,10 @@ extern "C" { #define SECURITY_CREATOR_GROUP_RID (0x00000001L) #define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L) #define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L) +#define SECURITY_OWNER_RIGHTS_RID (0x00000004L) +#define SECURITY_GROUP_RIGHTS_RID (0x00000005L) +#define SECURITY_CURRENT_OWNER_RID (0x000002FEL) +#define SECURITY_CURRENT_GROUP_RID (0x000002FFL) #define SECURITY_DIALUP_RID (0x00000001L) #define SECURITY_NETWORK_RID (0x00000002L) |