diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-10-22 13:31:19 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-10-22 13:31:19 +0000 |
commit | 8d7ae6bdd828ec14f4680d67914200e1e421ec49 (patch) | |
tree | 26c0e0557942902dec529177106c166afc7fb64e | |
parent | b0c111b3e907993d2032ef8478d3ade9e22a18ca (diff) | |
parent | bc4c0ff1343a311cc24933908ac6c4455af09031 (diff) | |
download | illumos-joyent-8d7ae6bdd828ec14f4680d67914200e1e421ec49.tar.gz |
[illumos-gate merge]
commit bc4c0ff1343a311cc24933908ac6c4455af09031
9880 Race in ZFS parallel mount
commit 975041dd3b571af240661f84d186e0cd0e36217b
9873 SMB logon fails during 1st second after service start
commit ab618543cc6fc4bc273c077ef5d247961cdb29d4
8158 Want named threads API
9857 proc manpages should have LIBRARY section
commit 62f63298eba531d48f87aa8c2089298cb7821962
9881 smbd terminated by SIGABRT after smb_account_free()
Conflicts:
usr/src/uts/common/sys/thread.h
usr/src/uts/common/fs/proc/prvnops.c
usr/src/uts/common/disp/thread.c
usr/src/man/man4/proc.4
usr/src/man/man1/ps.1
usr/src/lib/libc/port/threads/thr.c
26 files changed, 449 insertions, 226 deletions
diff --git a/usr/src/cmd/halt/Makefile b/usr/src/cmd/halt/Makefile index 98d8eccee4..a515a0a1ef 100644 --- a/usr/src/cmd/halt/Makefile +++ b/usr/src/cmd/halt/Makefile @@ -21,6 +21,7 @@ # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018 Joyent, Inc. # PROG = halt @@ -60,10 +61,10 @@ install := TARGET = install clean := TARGET = clean clobber := TARGET = clobber lint := TARGET = lint -lint := LINTFLAGS = -u +lint := LINTFLAGS += -u -all: $(PROG) +all: $(PROG) install: all $(ROOTUSRSBINPROG) $(ROOTLINKS) $(ROOTSYMLINKS) $(SUBDIRS) diff --git a/usr/src/cmd/sgs/libconv/Makefile.com b/usr/src/cmd/sgs/libconv/Makefile.com index c6287c433c..1bb482f706 100644 --- a/usr/src/cmd/sgs/libconv/Makefile.com +++ b/usr/src/cmd/sgs/libconv/Makefile.com @@ -21,7 +21,7 @@ # # Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2018, Joyent, Inc. +# Copyright 2018 Joyent, Inc. # LIBRARY = libconv.a @@ -124,8 +124,8 @@ $(LINTOUT64) := LDLIBS += -ldemangle-sys SGSMSGTARG= $(BLTOBJS:%_msg.o=../common/%.msg) -LINTFLAGS += -u -LINTFLAGS64 += -u +LINTFLAGS += -u -erroff=E_NAME_DECL_NOT_USED_DEF2 +LINTFLAGS64 += -u -erroff=E_NAME_DECL_NOT_USED_DEF2 CLEANFILES += $(BLTDATA) $(LINTOUTS) bld_vernote vernote.s CLOBBERFILES += $(LINTLIBS) diff --git a/usr/src/cmd/smbsrv/smbd/smbd_authsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_authsvc.c index 0b6af80bd8..b507148b72 100644 --- a/usr/src/cmd/smbsrv/smbd/smbd_authsvc.c +++ b/usr/src/cmd/smbsrv/smbd/smbd_authsvc.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -549,8 +549,12 @@ smbd_authsvc_oldreq(authsvc_context_t *ctx) token = smbd_user_auth_logon(&user_info); xdr_free(smb_logon_xdr, (char *)&user_info); - if (token == NULL) - return (NT_STATUS_ACCESS_DENIED); + if (token == NULL) { + rc = user_info.lg_status; + if (rc == 0) /* should not happen */ + rc = NT_STATUS_INTERNAL_ERROR; + return (rc); + } ctx->ctx_token = token; diff --git a/usr/src/cmd/smbsrv/smbd/smbd_logon.c b/usr/src/cmd/smbsrv/smbd/smbd_logon.c index ab6d4c2f7e..69b32b2ec9 100644 --- a/usr/src/cmd/smbsrv/smbd/smbd_logon.c +++ b/usr/src/cmd/smbsrv/smbd/smbd_logon.c @@ -77,6 +77,8 @@ static smb_audit_t *smbd_audit_unlink(uint32_t); /* * Invoked at user logon due to SmbSessionSetupX. Authenticate the * user, start an audit session and audit the event. + * + * On error, returns NULL, and status in user_info->lg_status */ smb_token_t * smbd_user_auth_logon(smb_logon_t *user_info) @@ -101,9 +103,16 @@ smbd_user_auth_logon(smb_logon_t *user_info) if (user_info->lg_username == NULL || user_info->lg_domain == NULL || user_info->lg_workstation == NULL) { + user_info->lg_status = NT_STATUS_INVALID_PARAMETER; return (NULL); } + /* + * Avoid modifying the caller-provided struct because it + * may or may not point to allocated strings etc. + * Copy to tmp_user, auth, then copy the (out) lg_status + * member back to the caller-provided struct. + */ tmp_user = *user_info; if (tmp_user.lg_username[0] == '\0') { tmp_user.lg_flags |= SMB_ATF_ANON; @@ -126,7 +135,12 @@ smbd_user_auth_logon(smb_logon_t *user_info) tmp_user.lg_e_domain = tmp_user.lg_domain; } - if ((token = smb_logon(&tmp_user)) == NULL) { + token = smb_logon(&tmp_user); + user_info->lg_status = tmp_user.lg_status; + + if (token == NULL) { + if (user_info->lg_status == 0) /* should not happen */ + user_info->lg_status = NT_STATUS_INTERNAL_ERROR; uid = ADT_NO_ATTRIB; gid = ADT_NO_ATTRIB; sid = NT_NULL_SIDSTR; @@ -147,12 +161,14 @@ smbd_user_auth_logon(smb_logon_t *user_info) if (adt_start_session(&ah, NULL, 0)) { syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m"); + user_info->lg_status = NT_STATUS_AUDIT_FAILED; goto errout; } if ((event = adt_alloc_event(ah, ADT_smbd_session)) == NULL) { syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(ADT_smbd_session): %m"); + user_info->lg_status = NT_STATUS_AUDIT_FAILED; goto errout; } @@ -172,6 +188,7 @@ smbd_user_auth_logon(smb_logon_t *user_info) if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW)) { syslog(LOG_AUTH | LOG_ALERT, "adt_set_user: %m"); adt_free_event(event); + user_info->lg_status = NT_STATUS_AUDIT_FAILED; goto errout; } @@ -187,6 +204,8 @@ smbd_user_auth_logon(smb_logon_t *user_info) if (token) { if ((entry = malloc(sizeof (smb_audit_t))) == NULL) { syslog(LOG_ERR, "smbd_user_auth_logon: %m"); + user_info->lg_status = + NT_STATUS_INSUFFICIENT_RESOURCES; goto errout; } @@ -199,6 +218,8 @@ smbd_user_auth_logon(smb_logon_t *user_info) smb_autohome_add(token); smbd_audit_link(entry); token->tkn_audit_sid = entry->sa_audit_sid; + + user_info->lg_status = NT_STATUS_SUCCESS; } free(buf); diff --git a/usr/src/cmd/smbsrv/smbd/smbd_ntlmssp.c b/usr/src/cmd/smbsrv/smbd/smbd_ntlmssp.c index 8027e3272b..80deababfa 100644 --- a/usr/src/cmd/smbsrv/smbd/smbd_ntlmssp.c +++ b/usr/src/cmd/smbsrv/smbd/smbd_ntlmssp.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -36,8 +36,8 @@ #define letohl(x) ((uint32_t)(x)) #else /* (BYTE_ORDER == LITTLE_ENDIAN) */ /* little-endian values on big-endian (swap) */ -#define letohl(x) BSWAP_32(x) -#define htolel(x) BSWAP_32(x) +#define letohl(x) BSWAP_32(x) +#define htolel(x) BSWAP_32(x) #endif /* (BYTE_ORDER == LITTLE_ENDIAN) */ typedef struct ntlmssp_backend { @@ -256,7 +256,7 @@ smbd_ntlmssp_negotiate(authsvc_context_t *ctx) NTLMSSP_MSGTYPE_CHALLENGE, /* 8: type (l) */ 0, 0, 0, /* filled later: 12: target name (wwl) */ be->srv_flags, /* 20: flags (l) */ - be->srv_challenge, /* 24: (8c) */ + be->srv_challenge, /* 24: (8c) */ 0, 0, /* 32: reserved (ll) */ 0, 0, 0); /* filled later: 40: target info (wwl) */ #define TARGET_NAME_OFFSET 12 @@ -489,7 +489,9 @@ smbd_ntlmssp_authenticate(authsvc_context_t *ctx) */ token = smbd_user_auth_logon(&user_info); if (token == NULL) { - status = NT_STATUS_ACCESS_DENIED; + status = user_info.lg_status; + if (status == 0) /* should not happen */ + status = NT_STATUS_INTERNAL_ERROR; goto errout; } diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c index fa5cbed73a..0361d5ae4f 100644 --- a/usr/src/cmd/svc/startd/graph.c +++ b/usr/src/cmd/svc/startd/graph.c @@ -6822,6 +6822,8 @@ repository_event_thread(void *unused) (void) pthread_setname_np(pthread_self(), "repository_event"); + (void) pthread_setname_np(pthread_self(), "repository_event"); + h = libscf_handle_create_bound_loop(); pg = safe_scf_pg_create(h); diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index f51996c646..eee08d81ca 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -77,6 +77,16 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.28 { + protected: + pthread_attr_getname_np; + pthread_attr_setname_np; + pthread_getname_np; + pthread_setname_np; + thr_getname; + thr_setname; +} ILLUMOS_0.27; + SYMBOL_VERSION ILLUMOS_0.27 { # memset_s(3C) and set_constraint_handler_s(3C) protected: abort_handler_s; diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c index 2db0041755..10302bae90 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -2411,14 +2411,11 @@ __nthreads(void) return (curthread->ul_uberdata->nthreads); } -/* "/native/proc/self/lwp/%u/lwpname" w/o stdio */ +/* "/proc/self/lwp/%u/lwpname" w/o stdio */ static void lwpname_path(pthread_t tid, char *buf, size_t bufsize) { - char *brand_root = curthread->ul_uberdata->ub_broot; - - (void) strlcpy(buf, brand_root == NULL ? "" : brand_root, bufsize); - (void) strlcat(buf, "/proc/self/lwp/", bufsize); + (void) strlcpy(buf, "/proc/self/lwp/", bufsize); ultos((uint64_t)tid, 10, buf + strlen(buf)); (void) strlcat(buf, "/lwpname", bufsize); } diff --git a/usr/src/lib/libzfs/common/libzfs_mount.c b/usr/src/lib/libzfs/common/libzfs_mount.c index cf15735f3f..9bbf4d2233 100644 --- a/usr/src/lib/libzfs/common/libzfs_mount.c +++ b/usr/src/lib/libzfs/common/libzfs_mount.c @@ -26,6 +26,7 @@ * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> * Copyright 2017 Joyent, Inc. * Copyright 2017 RackTop Systems. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -1142,19 +1143,28 @@ zfs_iter_cb(zfs_handle_t *zhp, void *data) /* * Sort comparator that compares two mountpoint paths. We sort these paths so * that subdirectories immediately follow their parents. This means that we - * effectively treat the '/' character as the lowest value non-nul char. An - * example sorted list using this comparator would look like: + * effectively treat the '/' character as the lowest value non-nul char. + * Since filesystems from non-global zones can have the same mountpoint + * as other filesystems, the comparator sorts global zone filesystems to + * the top of the list. This means that the global zone will traverse the + * filesystem list in the correct order and can stop when it sees the + * first zoned filesystem. In a non-global zone, only the delegated + * filesystems are seen. + * + * An example sorted list using this comparator would look like: * * /foo * /foo/bar * /foo/bar/baz * /foo/baz * /foo.bar + * /foo (NGZ1) + * /foo (NGZ2) * * The mounting code depends on this ordering to deterministically iterate * over filesystems in order to spawn parallel mount tasks. */ -int +static int mountpoint_cmp(const void *arga, const void *argb) { zfs_handle_t *const *zap = arga; @@ -1166,6 +1176,14 @@ mountpoint_cmp(const void *arga, const void *argb) const char *a = mounta; const char *b = mountb; boolean_t gota, gotb; + uint64_t zoneda, zonedb; + + zoneda = zfs_prop_get_int(za, ZFS_PROP_ZONED); + zonedb = zfs_prop_get_int(zb, ZFS_PROP_ZONED); + if (zoneda && !zonedb) + return (1); + if (!zoneda && zonedb) + return (-1); gota = (zfs_get_type(za) == ZFS_TYPE_FILESYSTEM); if (gota) { @@ -1379,6 +1397,8 @@ void zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles, size_t num_handles, zfs_iter_f func, void *data, boolean_t parallel) { + zoneid_t zoneid = getzoneid(); + /* * The ZFS_SERIAL_MOUNT environment variable is an undocumented * variable that can be used as a convenience to do a/b comparison @@ -1414,6 +1434,14 @@ zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles, */ for (int i = 0; i < num_handles; i = non_descendant_idx(handles, num_handles, i)) { + /* + * Since the mountpoints have been sorted so that the zoned + * filesystems are at the end, a zoned filesystem seen from + * the global zone means that we're done. + */ + if (zoneid == GLOBAL_ZONEID && + zfs_prop_get_int(handles[i], ZFS_PROP_ZONED)) + break; zfs_dispatch_mount(hdl, handles, num_handles, i, func, data, tq); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h index 838353b8e9..0506704d71 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBMLSVC_H @@ -66,7 +66,6 @@ extern boolean_t smb_locate_dc(char *, smb_domainex_t *); uint32_t smb_ddiscover_dns(char *, smb_domainex_t *); extern void smb_ddiscover_bad_dc(char *); extern void smb_ddiscover_refresh(void); -extern int smb_ddiscover_wait(void); extern int dssetup_check_service(void); extern void dssetup_clear_domain_info(void); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h index 2afc62a02d..0aa45b0292 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SMBSRV_MLSVC_H @@ -63,6 +63,8 @@ int netr_setup_authenticator(struct netr_info *, struct netr_authenticator *, struct netr_authenticator *); DWORD netr_validate_chain(struct netr_info *, struct netr_authenticator *); +uint32_t smb_netlogon_check(char *, char *); + int srvsvc_gettime(unsigned long *); void srvsvc_timecheck(char *, char *); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c index 74da88b2d5..51bef159c3 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <syslog.h> @@ -52,6 +52,9 @@ #define SMB_DCLOCATOR_TIMEOUT 45 /* seconds */ #define SMB_IS_FQDN(domain) (strchr(domain, '.') != NULL) +/* How long to pause after a failure to find any domain controllers. */ +int smb_ddiscover_failure_pause = 5; /* sec. */ + typedef struct smb_dclocator { smb_dcinfo_t sdl_dci; /* .dc_name .dc_addr */ char sdl_domain[SMB_PI_MAX_DOMAIN]; @@ -90,6 +93,14 @@ smb_dclocator_init(void) pthread_attr_t tattr; int rc; + /* + * We need the smb_ddiscover_service to run on startup, + * so it will enter smb_ddiscover_main() and put the + * SMB "domain cache" into "updating" state so clients + * trying to logon will wait while we're finding a DC. + */ + smb_dclocator.sdl_locate = B_TRUE; + (void) pthread_attr_init(&tattr); (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); rc = pthread_create(&smb_dclocator_thr, &tattr, @@ -241,6 +252,7 @@ smb_ddiscover_bad_dc(char *bad_dc) */ syslog(LOG_INFO, "smb_ddiscover, bad DC: %s", bad_dc); smb_dclocator.sdl_bad_dc = B_TRUE; + smb_domain_bad_dc(); /* In-line smb_ddiscover_kick */ if (!smb_dclocator.sdl_locate) { @@ -252,29 +264,6 @@ out: (void) mutex_unlock(&smb_dclocator.sdl_mtx); } -/* - * If domain discovery is running, wait for it to finish. - */ -int -smb_ddiscover_wait(void) -{ - timestruc_t to; - int rc = 0; - - (void) mutex_lock(&smb_dclocator.sdl_mtx); - - if (smb_dclocator.sdl_locate) { - to.tv_sec = SMB_DCLOCATOR_TIMEOUT; - to.tv_nsec = 0; - rc = cond_reltimedwait(&smb_dclocator.sdl_cv, - &smb_dclocator.sdl_mtx, &to); - } - - (void) mutex_unlock(&smb_dclocator.sdl_mtx); - - return (rc); -} - /* * ========================================================== @@ -354,10 +343,19 @@ smb_ddiscover_service(void *arg) status = smb_ddiscover_main(sdl->sdl_domain, &dxi); if (status == 0) smb_domain_save(); + (void) mutex_lock(&sdl->sdl_mtx); + sdl->sdl_status = status; - if (status == 0) + if (status == 0) { sdl->sdl_dci = dxi.d_dci; + } else { + syslog(LOG_DEBUG, "smb_ddiscover_service " + "retry after STATUS_%s", + xlate_nt_status(status)); + (void) sleep(smb_ddiscover_failure_pause); + goto find_again; + } /* * Run again if either of cfg_chg or bad_dc @@ -405,11 +403,6 @@ smb_ddiscover_main(char *domain, smb_domainex_t *dxi) return (NT_STATUS_INTERNAL_ERROR); } - if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS) { - syslog(LOG_DEBUG, "smb_ddiscover_main can't get lock"); - return (NT_STATUS_INTERNAL_ERROR); - } - status = smb_ads_lookup_msdcs(domain, &dxi->d_dci); if (status != 0) { syslog(LOG_DEBUG, "smb_ddiscover_main can't find DC (%s)", @@ -425,11 +418,15 @@ smb_ddiscover_main(char *domain, smb_domainex_t *dxi) goto out; } - smb_domain_update(dxi); + if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS) { + syslog(LOG_DEBUG, "smb_ddiscover_main can't get lock"); + status = NT_STATUS_INTERNAL_ERROR; + } else { + smb_domain_update(dxi); + smb_domain_end_update(); + } out: - smb_domain_end_update(); - /* Don't need the trusted domain list anymore. */ smb_domainex_free(dxi); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c index cdb6478f5b..d31fdd5ed0 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <sys/errno.h> @@ -104,10 +104,6 @@ mlsvc_timecheck(void *arg) if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) continue; - /* Avoid interfering with DC discovery. */ - if (smb_ddiscover_wait() != 0) - continue; - if (!smb_domain_getinfo(&di)) continue; diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c index b46cf99f87..956fbbad15 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c @@ -57,22 +57,16 @@ static DWORD mlsvc_join_noauth(smb_domainex_t *dxi, char *machine_name, char *machine_pw); - +/* + * This is called by smbd_dc_update just after we've learned about a + * new domain controller. Make sure we can authenticate with this DC. + */ DWORD mlsvc_netlogon(char *server, char *domain) { - mlsvc_handle_t netr_handle; DWORD status; - status = netr_open(server, domain, &netr_handle); - if (status != 0) { - syslog(LOG_NOTICE, "Failed to connect to %s " - "for domain %s (%s)", server, domain, - xlate_nt_status(status)); - return (status); - } - - status = netlogon_auth(server, &netr_handle, NETR_FLG_INIT); + status = smb_netlogon_check(server, domain); if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "Failed to establish NETLOGON " "credential chain with DC: %s (%s)", server, @@ -81,7 +75,6 @@ mlsvc_netlogon(char *server, char *domain) "domain controller does not match the local storage."); syslog(LOG_NOTICE, "To correct this, use 'smbadm join'"); } - (void) netr_close(&netr_handle); return (status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c index 6fdd3a9ca4..0a60a1a8fc 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* @@ -46,9 +46,7 @@ #include <smbsrv/smb_token.h> #include <mlsvc.h> -#define NETLOGON_ATTEMPTS 2 - -static uint32_t netlogon_logon(smb_logon_t *, smb_token_t *); +static uint32_t netlogon_logon(smb_logon_t *, smb_token_t *, smb_domainex_t *); static uint32_t netr_server_samlogon(mlsvc_handle_t *, netr_info_t *, char *, smb_logon_t *, smb_token_t *); static void netr_invalidate_chain(void); @@ -176,12 +174,19 @@ smb_logon_abort(void) * If the user is successfully authenticated, we build an * access token and the status will be NT_STATUS_SUCCESS. * Otherwise, the token contents are invalid. + * + * This will retry a few times for errors indicating that the + * current DC might have gone off-line or become too busy etc. + * With such errors, smb_ddiscover_bad_dc is called and then + * the smb_domain_getinfo call here waits for new DC info. */ +int smb_netr_logon_retries = 3; void smb_logon_domain(smb_logon_t *user_info, smb_token_t *token) { + smb_domainex_t di; uint32_t status; - int i; + int retries = smb_netr_logon_retries; if (user_info->lg_secmode != SMB_SECMODE_DOMAIN) return; @@ -189,21 +194,28 @@ smb_logon_domain(smb_logon_t *user_info, smb_token_t *token) if (user_info->lg_domain_type == SMB_DOMAIN_LOCAL) return; - for (i = 0; i < NETLOGON_ATTEMPTS; ++i) { + while (--retries > 0) { + + if (!smb_domain_getinfo(&di)) { + syslog(LOG_ERR, "logon DC getinfo failed"); + status = NT_STATUS_NO_LOGON_SERVERS; + goto out; + } + (void) mutex_lock(&netlogon_mutex); while (netlogon_busy && !netlogon_abort) (void) cond_wait(&netlogon_cv, &netlogon_mutex); if (netlogon_abort) { (void) mutex_unlock(&netlogon_mutex); - user_info->lg_status = NT_STATUS_REQUEST_ABORTED; - return; + status = NT_STATUS_REQUEST_ABORTED; + goto out; } netlogon_busy = B_TRUE; (void) mutex_unlock(&netlogon_mutex); - status = netlogon_logon(user_info, token); + status = netlogon_logon(user_info, token, &di); (void) mutex_lock(&netlogon_mutex); netlogon_busy = B_FALSE; @@ -212,71 +224,160 @@ smb_logon_domain(smb_logon_t *user_info, smb_token_t *token) (void) cond_signal(&netlogon_cv); (void) mutex_unlock(&netlogon_mutex); - if (status != NT_STATUS_CANT_ACCESS_DOMAIN_INFO) + switch (status) { + case NT_STATUS_BAD_NETWORK_PATH: + case NT_STATUS_BAD_NETWORK_NAME: + case RPC_NT_SERVER_TOO_BUSY: + /* + * May retry with a new DC, or if we're + * out of retries, will return... + */ + status = NT_STATUS_NO_LOGON_SERVERS; break; + default: + goto out; + } } +out: if (status != NT_STATUS_SUCCESS) syslog(LOG_INFO, "logon[%s\\%s]: %s", user_info->lg_e_domain, user_info->lg_e_username, xlate_nt_status(status)); - user_info->lg_status = status; } +/* + * Run a netr_server_samlogon call, dealing with the possible need to + * re-establish the NetLogon credential chain. If that fails, return + * NT_STATUS_DOMAIN_TRUST_INCONSISTENT indicating the machine account + * needs it's password reset (or whatever). Other errors are from the + * netr_server_samlogon() call including the many possibilities listed + * above that function. + */ static uint32_t -netlogon_logon(smb_logon_t *user_info, smb_token_t *token) +netlogon_logon(smb_logon_t *user_info, smb_token_t *token, smb_domainex_t *di) { - char resource_domain[SMB_PI_MAX_DOMAIN]; char server[MAXHOSTNAMELEN]; mlsvc_handle_t netr_handle; - smb_domainex_t di; uint32_t status; - int retries = 0; + boolean_t did_reauth = B_FALSE; - (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); + /* + * This netr_open call does the work to connect to the DC, + * get the IPC share, open the named pipe, RPC bind, etc. + */ + status = netr_open(di->d_dci.dc_name, di->d_primary.di_nbname, + &netr_handle); + if (status != 0) { + syslog(LOG_ERR, "netlogon remote open failed (%s)", + xlate_nt_status(status)); + return (status); + } - /* Avoid interfering with DC discovery. */ - if (smb_ddiscover_wait() != 0 || - !smb_domain_getinfo(&di)) { - netr_invalidate_chain(); - return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); + if (di->d_dci.dc_name[0] != '\0' && + (*netr_global_info.server != '\0')) { + (void) snprintf(server, sizeof (server), + "\\\\%s", di->d_dci.dc_name); + if (strncasecmp(netr_global_info.server, + server, strlen(server)) != 0) + netr_invalidate_chain(); } - do { - if (netr_open(di.d_dci.dc_name, di.d_primary.di_nbname, - &netr_handle) != 0) - return (NT_STATUS_OPEN_FAILED); - - if (di.d_dci.dc_name[0] != '\0' && - (*netr_global_info.server != '\0')) { - (void) snprintf(server, sizeof (server), - "\\\\%s", di.d_dci.dc_name); - if (strncasecmp(netr_global_info.server, - server, strlen(server)) != 0) - netr_invalidate_chain(); +reauth: + if ((netr_global_info.flags & NETR_FLG_VALID) == 0 || + !smb_match_netlogon_seqnum()) { + /* + * This does netr_server_req_challenge() and + * netr_server_authenticate2(), updating the + * current netlogon sequence number. + */ + status = netlogon_auth(di->d_dci.dc_name, &netr_handle, + NETR_FLG_NULL); + + if (status != 0) { + syslog(LOG_ERR, "netlogon remote auth failed (%s)", + xlate_nt_status(status)); + (void) netr_close(&netr_handle); + return (NT_STATUS_DOMAIN_TRUST_INCONSISTENT); } - if ((netr_global_info.flags & NETR_FLG_VALID) == 0 || - !smb_match_netlogon_seqnum()) { - status = netlogon_auth(di.d_dci.dc_name, &netr_handle, - NETR_FLG_NULL); + netr_global_info.flags |= NETR_FLG_VALID; + } - if (status != 0) { - (void) netr_close(&netr_handle); - return (NT_STATUS_LOGON_FAILURE); - } + status = netr_server_samlogon(&netr_handle, + &netr_global_info, di->d_dci.dc_name, user_info, token); - netr_global_info.flags |= NETR_FLG_VALID; + if (status == NT_STATUS_INSUFFICIENT_LOGON_INFO) { + if (!did_reauth) { + /* Call netlogon_auth() again, just once. */ + did_reauth = B_TRUE; + goto reauth; } + status = NT_STATUS_DOMAIN_TRUST_INCONSISTENT; + } + + (void) netr_close(&netr_handle); + + return (status); +} - status = netr_server_samlogon(&netr_handle, - &netr_global_info, di.d_dci.dc_name, user_info, token); +/* + * Helper for mlsvc_netlogon + * + * Call netlogon_auth with appropriate locks etc. + * Serialize like smb_logon_domain does for + * netlogon_logon / netlogon_auth + */ +uint32_t +smb_netlogon_check(char *server, char *domain) +{ + mlsvc_handle_t netr_handle; + uint32_t status; + + (void) mutex_lock(&netlogon_mutex); + while (netlogon_busy) + (void) cond_wait(&netlogon_cv, &netlogon_mutex); + + netlogon_busy = B_TRUE; + (void) mutex_unlock(&netlogon_mutex); + + /* + * This section like netlogon_logon(), but only does + * one pass and no netr_server_samlogon call. + */ + + status = netr_open(server, domain, + &netr_handle); + if (status != 0) { + syslog(LOG_ERR, "netlogon remote open failed (%s)", + xlate_nt_status(status)); + goto unlock_out; + } + + if ((netr_global_info.flags & NETR_FLG_VALID) == 0 || + !smb_match_netlogon_seqnum()) { + /* + * This does netr_server_req_challenge() and + * netr_server_authenticate2(), updating the + * current netlogon sequence number. + */ + status = netlogon_auth(server, &netr_handle, + NETR_FLG_NULL); + if (status != 0) { + syslog(LOG_ERR, "netlogon remote auth failed (%s)", + xlate_nt_status(status)); + } else { + netr_global_info.flags |= NETR_FLG_VALID; + } + } - (void) netr_close(&netr_handle); - } while (status == NT_STATUS_INSUFFICIENT_LOGON_INFO && retries++ < 3); + (void) netr_close(&netr_handle); - if (retries >= 3) - status = NT_STATUS_LOGON_FAILURE; +unlock_out: + (void) mutex_lock(&netlogon_mutex); + netlogon_busy = B_FALSE; + (void) cond_signal(&netlogon_cv); + (void) mutex_unlock(&netlogon_mutex); return (status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c index 237968469e..4ed50f2f1c 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c @@ -20,8 +20,8 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <unistd.h> @@ -417,6 +417,7 @@ smb_logon_fini(void) * attempt to authenticate the user. * * On success, a pointer to a new access token is returned. + * On failure, NULL return and status in user_info->lg_status */ smb_token_t * smb_logon(smb_logon_t *user_info) @@ -433,7 +434,6 @@ smb_logon(smb_logon_t *user_info) int i; user_info->lg_secmode = smb_config_get_secmode(); - user_info->lg_status = NT_STATUS_NO_SUCH_USER; if (smb_domain_lookup_name(user_info->lg_e_domain, &domain)) user_info->lg_domain_type = domain.di_type; @@ -446,6 +446,12 @@ smb_logon(smb_logon_t *user_info) return (NULL); } + /* + * If any logonop function takes significant action + * (logon or authoratative failure) it will change + * this status field to something else. + */ + user_info->lg_status = NT_STATUS_NO_SUCH_USER; for (i = 0; i < n_op; ++i) { (*ops[i])(user_info, token); @@ -455,10 +461,25 @@ smb_logon(smb_logon_t *user_info) if (user_info->lg_status == NT_STATUS_SUCCESS) { if (smb_token_setup_common(token)) - return (token); + return (token); /* success */ + /* + * (else) smb_token_setup_common failed, which usually + * means smb_token_sids2ids() failed to map some SIDs to + * Unix IDs. This indicates an idmap config problem. + */ + user_info->lg_status = NT_STATUS_INTERNAL_ERROR; } smb_token_destroy(token); + + /* + * Any unknown user or bad password should result in + * NT_STATUS_LOGON_FAILURE (so we don't give hints). + */ + if (user_info->lg_status == NT_STATUS_NO_SUCH_USER || + user_info->lg_status == NT_STATUS_WRONG_PASSWORD) + user_info->lg_status = NT_STATUS_LOGON_FAILURE; + return (NULL); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c b/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c index 724c509d8d..7a467f3628 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -158,7 +158,14 @@ smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server, goto errout; } if ((err = smb_ctx_get_ssn(ctx)) != 0) { - err = NT_STATUS_NETWORK_ACCESS_DENIED; + switch (err) { + case EAUTH: + err = NT_STATUS_NETWORK_ACCESS_DENIED; + break; + default: + err = NT_STATUS_BAD_NETWORK_PATH; + break; + } goto errout; } if ((err = smb_ctx_get_tree(ctx)) != 0) { diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h index 82d6bc1cc3..db6f6c6650 100644 --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h @@ -347,10 +347,10 @@ void libsmb_redirect_syslog(__FILE_TAG *fp, int priority); * 0x0004 The name is a W2K Domain name (a DNS name). */ #define SMBAUTH_NAME_TYPE_LIST_END 0x0000 -#define SMBAUTH_NAME_TYPE_SERVER_NETBIOS 0x0001 -#define SMBAUTH_NAME_TYPE_DOMAIN_NETBIOS 0x0002 +#define SMBAUTH_NAME_TYPE_SERVER_NETBIOS 0x0001 +#define SMBAUTH_NAME_TYPE_DOMAIN_NETBIOS 0x0002 #define SMBAUTH_NAME_TYPE_SERVER_DNS 0x0003 -#define SMBAUTH_NAME_TYPE_DOMAIN_DNS 0x0004 +#define SMBAUTH_NAME_TYPE_DOMAIN_DNS 0x0004 /* * smb_auth_name_entry_t @@ -662,6 +662,7 @@ void smb_domain_set_dns_info(char *, char *, char *, char *, char *, void smb_domain_set_trust_info(char *, char *, char *, uint32_t, uint32_t, uint32_t, smb_domain_t *); void smb_domain_current_dc(smb_dcinfo_t *); +void smb_domain_bad_dc(void); typedef struct smb_gsid { smb_sid_t *gs_sid; diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers index 2af8c7579b..aaa9d368b3 100644 --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers @@ -129,6 +129,7 @@ SYMBOL_VERSION SUNWprivate { smb_ctxbuf_printf; smb_dlclose; smb_dlopen; + smb_domain_bad_dc; smb_domain_current_dc; smb_domain_end_update; smb_domain_fini; diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c index 69769af98b..d920fccb01 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c @@ -22,7 +22,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -37,6 +37,7 @@ #include <stdio.h> #include <strings.h> #include <string.h> +#include <syslog.h> #include <unistd.h> #include <stdlib.h> #include <synch.h> @@ -70,10 +71,13 @@ typedef struct smb_domain_cache { list_t dc_cache; rwlock_t dc_cache_lck; - mutex_t dc_mtx; - cond_t dc_cv; uint32_t dc_state; uint32_t dc_nops; + mutex_t dc_mtx; + cond_t dc_cv; + /* domain controller information */ + cond_t dc_dci_cv; + boolean_t dc_dci_valid; smb_dcinfo_t dc_dci; } smb_domain_cache_t; @@ -90,7 +94,7 @@ static uint32_t smb_dcache_lock(int); static void smb_dcache_unlock(void); static void smb_dcache_remove(smb_domain_t *); static uint32_t smb_dcache_add(smb_domain_t *); -static boolean_t smb_dcache_getdc(smb_dcinfo_t *); +static boolean_t smb_dcache_getdc(smb_dcinfo_t *, boolean_t); static void smb_dcache_setdc(const smb_dcinfo_t *); static boolean_t smb_dcache_wait(void); static uint32_t smb_dcache_updating(void); @@ -113,6 +117,7 @@ smb_domain_init(uint32_t secmode) if ((rc = smb_domain_add_local()) != 0) return (rc); + bzero(&di, sizeof (di)); smb_domain_set_basic_info(NT_BUILTIN_DOMAIN_SIDSTR, "BUILTIN", "", &di); (void) smb_domain_add(SMB_DOMAIN_BUILTIN, &di); @@ -289,6 +294,8 @@ smb_domain_lookup_type(smb_domain_type_t type, smb_domain_t *di) /* * Returns primary domain information plus the name of * the selected domain controller. + * + * Returns TRUE on success. */ boolean_t smb_domain_getinfo(smb_domainex_t *dxi) @@ -297,10 +304,27 @@ smb_domain_getinfo(smb_domainex_t *dxi) /* Note: this waits for the dcache lock. */ rv = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &dxi->d_primary); - if (rv) - rv = smb_dcache_getdc(&dxi->d_dci); + if (!rv) { + syslog(LOG_ERR, "smb_domain_getinfo: no primary domain"); + return (B_FALSE); + } - return (rv); + /* + * The 2nd arg TRUE means this will wait for DC info. + * + * Note that we do NOT hold the dcache rwlock here + * (not even as reader) because we already have what we + * need from the dcache (our primary domain) and we don't + * want to interfere with the DC locator which will take + * the dcache lock as writer to update the domain info. + */ + rv = smb_dcache_getdc(&dxi->d_dci, B_TRUE); + if (!rv) { + syslog(LOG_ERR, "smb_domain_getinfo: no DC info"); + return (B_FALSE); + } + + return (B_TRUE); } /* @@ -310,7 +334,7 @@ smb_domain_getinfo(smb_domainex_t *dxi) void smb_domain_current_dc(smb_dcinfo_t *dci) { - (void) smb_dcache_getdc(dci); + (void) smb_dcache_getdc(dci, B_FALSE); } /* @@ -334,6 +358,18 @@ smb_domain_end_update(void) } /* + * Mark the current domain controller (DC) info invalid + * until the DC locator calls smb_domain_update(). + */ +void +smb_domain_bad_dc(void) +{ + (void) mutex_lock(&smb_dcache.dc_mtx); + smb_dcache.dc_dci_valid = B_FALSE; + (void) mutex_unlock(&smb_dcache.dc_mtx); +} + +/* * Updates the cache with given information for the primary * domain, possible trusted domains and the selected domain * controller. @@ -484,6 +520,7 @@ smb_domain_set_dns_info(char *sid, char *nb_domain, char *fq_domain, if (di == NULL || forest == NULL || guid == NULL) return; + /* Caller zeros out *di before this. */ smb_domain_set_basic_info(sid, nb_domain, fq_domain, di); (void) strlcpy(di->di_u.di_dns.ddi_forest, forest, MAXHOSTNAMELEN); (void) strlcpy(di->di_u.di_dns.ddi_guid, guid, @@ -500,6 +537,7 @@ smb_domain_set_trust_info(char *sid, char *nb_domain, char *fq_domain, if (di == NULL) return; + /* Caller zeros out *di before this. */ di->di_type = SMB_DOMAIN_TRUSTED; ti = &di->di_u.di_trust; smb_domain_set_basic_info(sid, nb_domain, fq_domain, di); @@ -540,6 +578,7 @@ smb_domain_add_local(void) return (SMB_DOMAIN_NOMACHINE_SID); } + bzero(&di, sizeof (di)); *fq_name = '\0'; (void) smb_getfqhostname(fq_name, MAXHOSTNAMELEN); smb_domain_set_basic_info(lsidstr, hostname, fq_name, &di); @@ -572,6 +611,7 @@ smb_domain_add_primary(uint32_t secmode) if ((rc != SMBD_SMF_OK) || (*nb_name == '\0')) return (SMB_DOMAIN_NODOMAIN_NAME); + bzero(&di, sizeof (di)); (void) smb_getfqdomainname(fq_name, MAXHOSTNAMELEN); smb_domain_set_basic_info(sidstr, nb_name, fq_name, &di); (void) smb_domain_add(SMB_DOMAIN_PRIMARY, &di); @@ -596,6 +636,7 @@ smb_dcache_create(void) smb_dcache.dc_nops = 0; bzero(&smb_dcache.dc_dci, sizeof (smb_dcache.dc_dci)); + smb_dcache.dc_dci_valid = B_FALSE; smb_dcache.dc_state = SMB_DCACHE_STATE_READY; (void) mutex_unlock(&smb_dcache.dc_mtx); } @@ -652,6 +693,7 @@ smb_dcache_lock(int mode) switch (smb_dcache.dc_state) { case SMB_DCACHE_STATE_NONE: case SMB_DCACHE_STATE_DESTROYING: + default: (void) mutex_unlock(&smb_dcache.dc_mtx); return (SMB_DOMAIN_INTERNAL_ERR); @@ -668,7 +710,7 @@ smb_dcache_lock(int mode) } /* FALLTHROUGH */ - default: + case SMB_DCACHE_STATE_READY: smb_dcache.dc_nops++; break; } @@ -733,19 +775,40 @@ smb_dcache_setdc(const smb_dcinfo_t *dci) { (void) mutex_lock(&smb_dcache.dc_mtx); smb_dcache.dc_dci = *dci; /* struct assignment! */ + smb_dcache.dc_dci_valid = B_TRUE; + (void) cond_broadcast(&smb_dcache.dc_dci_cv); (void) mutex_unlock(&smb_dcache.dc_mtx); } /* - * Return B_TRUE if we have DC information. + * Get information about our domain controller. If the wait arg + * is true, wait for the DC locator to finish before copying. + * Returns TRUE on success (have DC info). */ static boolean_t -smb_dcache_getdc(smb_dcinfo_t *dci) +smb_dcache_getdc(smb_dcinfo_t *dci, boolean_t wait) { + timestruc_t to; + boolean_t rv; + int err; + + to.tv_sec = time(NULL) + SMB_DCACHE_UPDATE_WAIT; + to.tv_nsec = 0; + (void) mutex_lock(&smb_dcache.dc_mtx); + + while (wait && !smb_dcache.dc_dci_valid) { + err = cond_timedwait(&smb_dcache.dc_dci_cv, + &smb_dcache.dc_mtx, &to); + if (err == ETIME) + break; + } *dci = smb_dcache.dc_dci; /* struct assignment! */ + rv = smb_dcache.dc_dci_valid; + (void) mutex_unlock(&smb_dcache.dc_mtx); - return (dci->dc_name[0] != '\0'); + + return (rv); } /* @@ -759,10 +822,12 @@ smb_dcache_wait(void) timestruc_t to; int err; - to.tv_sec = SMB_DCACHE_UPDATE_WAIT; + assert(MUTEX_HELD(&smb_dcache.dc_mtx)); + + to.tv_sec = time(NULL) + SMB_DCACHE_UPDATE_WAIT; to.tv_nsec = 0; while (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING) { - err = cond_reltimedwait(&smb_dcache.dc_cv, + err = cond_timedwait(&smb_dcache.dc_cv, &smb_dcache.dc_mtx, &to); if (err == ETIME) break; diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c index e236b56724..68a7aa2131 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c @@ -23,6 +23,7 @@ * Use is subject to license terms. * * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 RackTop Systems. */ #include <strings.h> @@ -91,7 +92,7 @@ static smb_lwka_t *smb_lwka_lookup_sid(smb_sid_t *); * * NT_STATUS_NOT_FOUND This is not a local account * NT_STATUS_NONE_MAPPED It's a local account but cannot be - * translated. + * translated. * other error status codes. */ uint32_t @@ -201,7 +202,7 @@ smb_sam_lookup_name(char *domain, char *name, uint16_t type, * * NT_STATUS_NOT_FOUND This is not a local account * NT_STATUS_NONE_MAPPED It's a local account but cannot be - * translated. + * translated. * other error status codes. */ uint32_t @@ -477,6 +478,7 @@ smb_sam_grp_ismember(const char *gname, smb_sid_t *sid) /* * Frees memories allocated for the passed account fields. + * Initializes @account after all. */ void smb_account_free(smb_account_t *account) @@ -485,6 +487,8 @@ smb_account_free(smb_account_t *account) free(account->a_domain); smb_sid_free(account->a_sid); smb_sid_free(account->a_domsid); + + bzero(account, sizeof (smb_account_t)); } /* diff --git a/usr/src/man/man1/ps.1 b/usr/src/man/man1/ps.1 index 9f2fb063ca..2ed67d399e 100644 --- a/usr/src/man/man1/ps.1 +++ b/usr/src/man/man1/ps.1 @@ -885,14 +885,14 @@ is a version of the argument list as it was passed to the command when it started, or is a version of the arguments as they might have been modified by the application. Applications cannot depend on being able to modify their argument list and having that modification be reflected in the output of -\fBps\fR. The Solaris implementation limits the string to 80 bytes; the string +\fBps\fR. The illumos implementation limits the string to 80 bytes; the string is the version of the argument list as it was passed to the command when it started. .RE .sp .LP -The following names are recognized in the Solaris implementation: +The following names are recognized in the illumos implementation: .sp .ne 2 .na @@ -1187,7 +1187,7 @@ The data model of the process, printed in the same manner as via .sp .LP Only \fBcomm\fR, \fBlwpname\fR, and \fBargs\fR are allowed to contain blank -characters; all others, including the Solaris implementation variables, are not. +characters; all others, including the illumos implementation variables, are not. .sp .LP The following table specifies the default header to be used in the POSIX locale @@ -1214,7 +1214,7 @@ pid PID .sp .LP -The following table lists the Solaris implementation format specifiers and the +The following table lists the illumos implementation format specifiers and the default header used with each. .sp diff --git a/usr/src/man/man4/proc.4 b/usr/src/man/man4/proc.4 index b60c0085c7..c9f74a90c5 100644 --- a/usr/src/man/man4/proc.4 +++ b/usr/src/man/man4/proc.4 @@ -5,58 +5,33 @@ .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.Dd "August 22, 2018" -.Dt PROC 4 -.Os -.Sh NAME -.Nm proc -.Nd /proc, the process file system -.Sh DESCRIPTION -.Pa /proc -is a file system that provides access to the state of each process -and light-weight process (lwp) in the system. -The name of each entry in the -.Pa /proc -directory is a decimal number corresponding to a process-ID. -These entries are themselves subdirectories. -Access to process state is provided by additional files contained within each -subdirectory; the hierarchy is described more completely below. -In this document, -.Dq Pa /proc file -refers to a non-directory file within the hierarchy rooted at -.Pa /proc . -The owner of each -.Pa /proc -file and subdirectory is determined by the user-ID of the process. -.Pp -.Pa /proc -can be mounted on any mount point, in addition to the standard -.Pa /proc -mount point, and can be mounted several places at once. -Such additional mounts are allowed in order to facilitate the confinement of -processes to subtrees of the file system via -.Xr chroot 2 -and yet allow such processes access to commands like -.Xr ps 1 . -.Pp -Standard system calls are used to access -.Pa /proc -files: -.Xr open 2 , -.Xr close 2 , -.Xr read 2 , -and -.Xr write 2 -(including -.Xr readv 2 , -.Xr writev 2 , -.Xr pread 2 , -and -.Xr pwrite 2 ) . -Most files describe process state and can only be opened for reading. -.Pa ctl -and -.Pa lwpctl +.TH PROC 4 "August 22, 2018" +.SH NAME +proc \- /proc, the process file system +.SH DESCRIPTION +.LP +\fB/proc\fR is a file system that provides access to the state of each process +and light-weight process (lwp) in the system. The name of each entry in the +\fB/proc\fR directory is a decimal number corresponding to a process-ID. These +entries are themselves subdirectories. Access to process state is provided by +additional files contained within each subdirectory; the hierarchy is described +more completely below. In this document, ``\fB/proc\fR file'' refers to a +non-directory file within the hierarchy rooted at \fB/proc\fR. The owner of +each \fB/proc\fR file and subdirectory is determined by the user-ID of the +process. +.sp +.LP +\fB/proc\fR can be mounted on any mount point, in addition to the standard +\fB/proc\fR mount point, and can be mounted several places at once. Such +additional mounts are allowed in order to facilitate the confinement of +processes to subtrees of the file system via \fBchroot\fR(1M) and yet allow +such processes access to commands like \fBps\fR(1). +.sp +.LP +Standard system calls are used to access \fB/proc\fR files: \fBopen\fR(2), +\fBclose\fR(2), \fBread\fR(2), and \fBwrite\fR(2) (including \fBreadv\fR(2), +\fBwritev\fR(2), \fBpread\fR(2), and \fBpwrite\fR(2)). Most files describe +process state and can only be opened for reading. \fBctl\fR and \fBlwpctl\fR (control) files permit manipulation of process state and can only be opened for writing. .Pa as @@ -1645,26 +1620,18 @@ contains the following entries: Write-only control file. The messages written to this file affect the specific lwp rather than the representative lwp, as is the case for the process's -.Pa ctl -file. -.Ss lwpname -A buffer of -.Dv THREAD_NAME_MAX -bytes representing the LWP name; the buffer is -zero-filled if the thread name is shorter than the buffer. -If no thread name is set, the buffer contains the empty string. -A read with a buffer shorter than -.Dv THREAD_NAME_MAX -bytes is not guaranteed -to be NUL-terminated. -Writing to this file will set the LWP name for the specific lwp. -This file may not be present in older operating system versions. -.Dv THREAD_NAME_MAX -may increase in the future; clients should be prepared for this. -.Ss lwpstatus -lwp-specific state information. -This file contains the -.Vt lwpstatus +\fBctl\fR file. +.SS lwpname +A buffer of \fBTHREAD_NAME_MAX\fR bytes representing the LWP name; the buffer is +zero-filled if the thread name is shorter than the buffer. If no thread name is +set, the buffer contains the empty string. A read with a buffer shorter than +\fBTHREAD_NAME_MAX\fR bytes is not guaranteed to be NUL-terminated. Writing to +this file will set the LWP name for the specific lwp. This file may not be +present in older operating system versions. \fBTHREAD_NAME_MAX\fR may increase +in the future; clients should be prepared for this. +.SS "lwpstatus" +.LP +lwp-specific state information. This file contains the \fBlwpstatus\fR structure for the specific lwp as described above for the representative lwp in the process's .Pa status diff --git a/usr/src/uts/common/exec/elf/elf_notes.c b/usr/src/uts/common/exec/elf/elf_notes.c index d977d28540..6a024d0d1f 100644 --- a/usr/src/uts/common/exec/elf/elf_notes.c +++ b/usr/src/uts/common/exec/elf/elf_notes.c @@ -26,7 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. - * Copyright 2018, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #include <sys/types.h> diff --git a/usr/src/uts/common/fs/proc/prvnops.c b/usr/src/uts/common/fs/proc/prvnops.c index 57d01c86f0..b9ab00d745 100644 --- a/usr/src/uts/common/fs/proc/prvnops.c +++ b/usr/src/uts/common/fs/proc/prvnops.c @@ -2919,7 +2919,7 @@ pr_write_lwpname(prnode_t *pnp, uio_t *uiop) VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0'); for (size_t i = 0; lwpname[i] != '\0'; i++) { - if (!isprint(lwpname[i])) { + if (!ISPRINT(lwpname[i])) { kmem_free(lwpname, THREAD_NAME_MAX); return (EINVAL); } @@ -4860,6 +4860,10 @@ prgetnode(vnode_t *dp, prnodetype_t type) pnp->pr_mode = 0600; /* read-write by owner only */ break; + case PR_LWPNAME: + pnp->pr_mode = 0644; /* readable by all + owner can write */ + break; + case PR_PSINFO: case PR_LWPNAME: pnp->pr_mode = 0644; /* readable by all + owner can write */ diff --git a/usr/src/uts/common/sys/procfs.h b/usr/src/uts/common/sys/procfs.h index 38c006f8f0..99da92ab79 100644 --- a/usr/src/uts/common/sys/procfs.h +++ b/usr/src/uts/common/sys/procfs.h @@ -25,7 +25,7 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. - * Copyright 2018, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #ifndef _SYS_PROCFS_H |