diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-11-19 18:47:18 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2014-11-19 18:47:18 +0000 |
commit | 9df4635546174b6e0dd39adace8563ebd85536e1 (patch) | |
tree | 76e4897e087a14909e1231d140e34da36180a28b /usr/src | |
parent | d0b6aa18f1151b5678b45ba5235417d2fda31967 (diff) | |
parent | 1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9f (diff) | |
download | illumos-joyent-9df4635546174b6e0dd39adace8563ebd85536e1.tar.gz |
[illumos-gate merge]
commit 1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9f
5316 allow smbadm join to use RPC
commit 177d5b5f8c0e969013441207a0a705ae66b08cf7
5331 want sockaddr(3SOCKET)
Manifests:
usr/src/pkg/manifests/system-library.man3socket.inc
Diffstat (limited to 'usr/src')
74 files changed, 1951 insertions, 1786 deletions
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.c b/usr/src/cmd/idmap/idmapd/idmap_config.c index 02ae8029cf..b8c2867489 100644 --- a/usr/src/cmd/idmap/idmapd/idmap_config.c +++ b/usr/src/cmd/idmap/idmapd/idmap_config.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ @@ -1455,6 +1455,11 @@ idmap_cfg_load_smf(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg, if (rc != 0) (*errors)++; + rc = get_val_bool(handles, "use_ads", + &pgcfg->use_ads, B_TRUE); + if (rc != 0) + (*errors)++; + rc = get_val_bool(handles, "use_lsa", &pgcfg->use_lsa, B_TRUE); if (rc != 0) @@ -1797,6 +1802,12 @@ idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg) { ad_disc_t ad_ctx = handles->ad_ctx; + if (pgcfg->use_ads == B_FALSE) { + if (DBG(CONFIG, 1)) + idmapdlog(LOG_DEBUG, "ADS disabled."); + return; + } + if (DBG(CONFIG, 1)) idmapdlog(LOG_DEBUG, "Running discovery."); @@ -1916,6 +1927,9 @@ idmap_cfg_load(idmap_cfg_t *cfg, int flags) changed += update_bool(&live_pgcfg->eph_map_unres_sids, &new_pgcfg.eph_map_unres_sids, "unresolvable_sid_mapping"); + changed += update_bool(&live_pgcfg->use_ads, + &new_pgcfg.use_ads, "use_ads"); + changed += update_bool(&live_pgcfg->use_lsa, &new_pgcfg.use_lsa, "use_lsa"); diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.h b/usr/src/cmd/idmap/idmapd/idmap_config.h index 66e5431031..31ae7b6ad1 100644 --- a/usr/src/cmd/idmap/idmapd/idmap_config.h +++ b/usr/src/cmd/idmap/idmapd/idmap_config.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #ifndef _IDMAP_CONFIG_H @@ -108,6 +108,7 @@ typedef struct idmap_pg_config { char *nldap_winname_attr; int directory_based_mapping; /* enum */ boolean_t eph_map_unres_sids; + boolean_t use_ads; boolean_t use_lsa; boolean_t disable_cross_forest_trusts; } idmap_pg_config_t; diff --git a/usr/src/cmd/idmap/idmapd/init.c b/usr/src/cmd/idmap/idmapd/init.c index 43c18b6293..3e5dde7ad8 100644 --- a/usr/src/cmd/idmap/idmapd/init.c +++ b/usr/src/cmd/idmap/idmapd/init.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* @@ -119,8 +120,12 @@ reload_gcs() int num_trustfor = pgcfg->num_trusted_forests; ad_disc_domainsinforest_t *domain_in_forest; - if (pgcfg->domain_name == NULL) { - /* No domain name specified - workgroup mode. */ + if (pgcfg->use_ads == B_FALSE || + pgcfg->domain_name == NULL) { + /* + * ADS disabled, or no domain name specified. + * Not using adutils. (but still can use lsa) + */ new_gcs = NULL; new_num_gcs = 0; goto out; @@ -248,8 +253,12 @@ reload_dcs(void) int old_num_dcs = _idmapdstate.num_dcs; idmap_pg_config_t *pgcfg = &_idmapdstate.cfg->pgcfg; - if (pgcfg->domain_name == NULL) { - /* No domain name specified - workgroup mode. */ + if (pgcfg->use_ads == B_FALSE || + pgcfg->domain_name == NULL) { + /* + * ADS disabled, or no domain name specified. + * Not using adutils. (but still can use lsa) + */ new_dcs = NULL; new_num_dcs = 0; goto out; diff --git a/usr/src/cmd/smbsrv/smbadm/smbadm.c b/usr/src/cmd/smbsrv/smbadm/smbadm.c index 7874a71bed..07887fa7a3 100644 --- a/usr/src/cmd/smbsrv/smbadm/smbadm.c +++ b/usr/src/cmd/smbsrv/smbadm/smbadm.c @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -229,8 +229,14 @@ smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd) return; case HELP_JOIN: +#if 0 /* Don't document "-p" yet, still needs work (NX 11960) */ + (void) fprintf(fp, gettext("\t%s -p domain\n" + "\t%s -u username domain\n\t%s -w workgroup\n"), + cmd->name, cmd->name, cmd->name); +#else (void) fprintf(fp, gettext("\t%s -u username domain\n" "\t%s -w workgroup\n"), cmd->name, cmd->name); +#endif return; case HELP_LIST: @@ -457,45 +463,25 @@ smbadm_join(int argc, char **argv) uint32_t mode = 0; char option; - while ((option = getopt(argc, argv, "u:w:")) != -1) { + while ((option = getopt(argc, argv, "pu:w")) != -1) { + if (mode != 0) { + (void) fprintf(stderr, gettext( + "join options are mutually exclusive\n")); + smbadm_usage(B_FALSE); + } switch (option) { - case 'w': - if (mode != 0) { - (void) fprintf(stderr, - gettext("-u and -w must only appear " - "once and are mutually exclusive\n")); - smbadm_usage(B_FALSE); - } - - mode = SMB_SECMODE_WORKGRP; - domain = optarg; + case 'p': + mode = SMB_SECMODE_DOMAIN; + /* leave username = NULL */ break; case 'u': - if (mode != 0) { - (void) fprintf(stderr, - gettext("-u and -w must only appear " - "once and are mutually exclusive\n")); - smbadm_usage(B_FALSE); - } - mode = SMB_SECMODE_DOMAIN; username = optarg; + break; - if ((domain = argv[optind]) == NULL) { - /* - * The domain was not specified as a separate - * argument, check for the combination forms. - */ - (void) strlcpy(buf, username, sizeof (buf)); - smbadm_extract_domain(buf, &username, &domain); - } - - if ((username == NULL) || (*username == '\0')) { - (void) fprintf(stderr, - gettext("missing username\n")); - smbadm_usage(B_FALSE); - } + case 'w': + mode = SMB_SECMODE_WORKGRP; break; default: @@ -504,16 +490,28 @@ smbadm_join(int argc, char **argv) } } + if (optind < argc) + domain = argv[optind]; + + if (username != NULL && domain == NULL) { + /* + * The domain was not specified as a separate + * argument, check for the combination forms. + */ + (void) strlcpy(buf, username, sizeof (buf)); + smbadm_extract_domain(buf, &username, &domain); + } + if ((domain == NULL) || (*domain == '\0')) { (void) fprintf(stderr, gettext("missing %s name\n"), (mode == SMB_SECMODE_WORKGRP) ? "workgroup" : "domain"); smbadm_usage(B_FALSE); } - if (mode == SMB_SECMODE_WORKGRP) + if (mode == SMB_SECMODE_WORKGRP) { return (smbadm_join_workgroup(domain)); - else - return (smbadm_join_domain(domain, username)); + } + return (smbadm_join_domain(domain, username)); } /* @@ -582,37 +580,46 @@ smbadm_join_domain(const char *domain, const char *username) if (!smbadm_join_prompt(jdi.domain_name)) return (0); - if ((p = strchr(username, '+')) != NULL) { - ++p; - - len = (int)(p - username); - if (len > sizeof (jdi.domain_name)) - len = sizeof (jdi.domain_name); - - (void) strlcpy(jdi.domain_username, username, len); - (void) strlcpy(jdi.domain_passwd, p, - sizeof (jdi.domain_passwd)); - } else { - (void) strlcpy(jdi.domain_username, username, - sizeof (jdi.domain_username)); - } + /* + * Note: username is null for "unsecure join" + * (join using a pre-created computer account) + * No password either. + */ + if (username != NULL) { + if ((p = strchr(username, '+')) != NULL) { + ++p; - if (smb_name_validate_account(jdi.domain_username) != ERROR_SUCCESS) { - (void) fprintf(stderr, - gettext("username contains invalid characters\n")); - smbadm_usage(B_FALSE); - } + len = (int)(p - username); + if (len > sizeof (jdi.domain_name)) + len = sizeof (jdi.domain_name); - if (*jdi.domain_passwd == '\0') { - prompt = gettext("Enter domain password: "); + (void) strlcpy(jdi.domain_username, username, len); + (void) strlcpy(jdi.domain_passwd, p, + sizeof (jdi.domain_passwd)); + } else { + (void) strlcpy(jdi.domain_username, username, + sizeof (jdi.domain_username)); + } - if ((p = getpassphrase(prompt)) == NULL) { - (void) fprintf(stderr, gettext("missing password\n")); + if (smb_name_validate_account(jdi.domain_username) + != ERROR_SUCCESS) { + (void) fprintf(stderr, + gettext("username contains invalid characters\n")); smbadm_usage(B_FALSE); } - (void) strlcpy(jdi.domain_passwd, p, - sizeof (jdi.domain_passwd)); + if (*jdi.domain_passwd == '\0') { + prompt = gettext("Enter domain password: "); + + if ((p = getpassphrase(prompt)) == NULL) { + (void) fprintf(stderr, gettext( + "missing password\n")); + smbadm_usage(B_FALSE); + } + + (void) strlcpy(jdi.domain_passwd, p, + sizeof (jdi.domain_passwd)); + } } (void) printf(gettext("Joining %s ... this may take a minute ...\n"), @@ -635,6 +642,19 @@ smbadm_join_domain(const char *domain, const char *username) bzero(&jdi, sizeof (jdi)); return (1); + case NT_STATUS_BAD_NETWORK_PATH: + (void) fprintf(stderr, + gettext("failed to resolve domain controller name\n")); + bzero(&jdi, sizeof (jdi)); + return (1); + + case NT_STATUS_NETWORK_ACCESS_DENIED: + case NT_STATUS_BAD_NETWORK_NAME: + (void) fprintf(stderr, + gettext("failed connecting to domain controller\n")); + bzero(&jdi, sizeof (jdi)); + return (1); + default: (void) fprintf(stderr, gettext("failed to join %s: %s\n"), jdi.domain_name, xlate_nt_status(status)); diff --git a/usr/src/cmd/smbsrv/smbd/smbd_join.c b/usr/src/cmd/smbsrv/smbd/smbd_join.c index 54fcaccfbb..74d5fac9be 100644 --- a/usr/src/cmd/smbsrv/smbd/smbd_join.c +++ b/usr/src/cmd/smbsrv/smbd/smbd_join.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #include <syslog.h> @@ -48,8 +49,7 @@ static cond_t smbd_dc_cv; static void *smbd_dc_monitor(void *); static void smbd_dc_update(void); -static boolean_t smbd_set_netlogon_cred(void); -static int smbd_get_kpasswd_srv(char *, size_t); +/* Todo: static boolean_t smbd_set_netlogon_cred(void); */ static uint32_t smbd_join_workgroup(smb_joininfo_t *); static uint32_t smbd_join_domain(smb_joininfo_t *); @@ -164,8 +164,8 @@ smbd_dc_update(void) { char domain[MAXHOSTNAMELEN]; smb_domainex_t info; - smb_domain_t *primary; - + smb_domain_t *di; + DWORD status; if (smb_getfqdomainname(domain, MAXHOSTNAMELEN) != 0) { (void) smb_getdomainname(domain, MAXHOSTNAMELEN); @@ -175,26 +175,24 @@ smbd_dc_update(void) if (!smb_locate_dc(domain, "", &info)) { smb_log(smbd.s_loghd, LOG_NOTICE, "smbd_dc_update: %s: locate failed", domain); - } else { - primary = &info.d_primary; + return; + } - smb_config_setdomaininfo(primary->di_nbname, - primary->di_fqname, - primary->di_sid, - primary->di_u.di_dns.ddi_forest, - primary->di_u.di_dns.ddi_guid); + di = &info.d_primary; + smb_log(smbd.s_loghd, LOG_NOTICE, + "smbd_dc_update: %s: located %s", domain, info.d_dc); - smb_log(smbd.s_loghd, LOG_NOTICE, - "smbd_dc_update: %s: located %s", domain, info.d_dc); - } + status = mlsvc_netlogon(info.d_dc, di->di_nbname); + if (status != NT_STATUS_SUCCESS) { + syslog(LOG_NOTICE, + "failed to establish NETLOGON credential chain"); - if (smbd_set_netlogon_cred()) { /* * Restart required because the domain changed * or the credential chain setup failed. */ smb_log(smbd.s_loghd, LOG_NOTICE, - "smbd_dc_update: %s: smb/server restart required"); + "smbd_dc_update: smb/server restart required"); if (smb_smf_restart_service() != 0) smb_log(smbd.s_loghd, LOG_ERR, @@ -225,148 +223,6 @@ smbd_join(smb_joininfo_t *info) return (status); } -/* - * smbd_set_netlogon_cred - * - * If the system is joined to an AD domain via kclient, SMB daemon will need - * to establish the NETLOGON credential chain. - * - * Since the kclient has updated the machine password stored in SMF - * repository, the cached ipc_info must be updated accordingly by calling - * smb_ipc_commit. - * - * Due to potential replication delays in a multiple DC environment, the - * NETLOGON rpc request must be sent to the DC, to which the KPASSWD request - * is sent. If the DC discovered by the SMB daemon is different than the - * kpasswd server, the current connection with the DC will be torn down - * and a DC discovery process will be triggered to locate the kpasswd - * server. - * - * If joining a new domain, the domain_name property must be set after a - * successful credential chain setup. - */ -static boolean_t -smbd_set_netlogon_cred(void) -{ - char kpasswd_srv[MAXHOSTNAMELEN]; - char kpasswd_domain[MAXHOSTNAMELEN]; - char sam_acct[SMB_SAMACCT_MAXLEN]; - char ipc_usr[SMB_USERNAME_MAXLEN]; - char *dom; - boolean_t new_domain = B_FALSE; - smb_domainex_t dxi; - smb_domain_t *di; - - if (smb_match_netlogon_seqnum()) - return (B_FALSE); - - (void) smb_config_getstr(SMB_CI_KPASSWD_SRV, kpasswd_srv, - sizeof (kpasswd_srv)); - - if (*kpasswd_srv == '\0') - return (B_FALSE); - - /* - * If the domain join initiated by smbadm join CLI is in - * progress, don't do anything. - */ - (void) smb_getsamaccount(sam_acct, sizeof (sam_acct)); - smb_ipc_get_user(ipc_usr, SMB_USERNAME_MAXLEN); - if (smb_strcasecmp(ipc_usr, sam_acct, 0)) - return (B_FALSE); - - di = &dxi.d_primary; - if (!smb_domain_getinfo(&dxi)) - (void) smb_getfqdomainname(di->di_fqname, MAXHOSTNAMELEN); - - (void) smb_config_getstr(SMB_CI_KPASSWD_DOMAIN, kpasswd_domain, - sizeof (kpasswd_domain)); - - if (*kpasswd_domain != '\0' && - smb_strcasecmp(kpasswd_domain, di->di_fqname, 0)) { - dom = kpasswd_domain; - new_domain = B_TRUE; - } else { - dom = di->di_fqname; - } - - /* - * DC discovery will be triggered if the domain info is not - * currently cached or the SMB daemon has previously discovered a DC - * that is different than the kpasswd server. - */ - if (new_domain || smb_strcasecmp(dxi.d_dc, kpasswd_srv, 0) != 0) { - if (*dxi.d_dc != '\0') - mlsvc_disconnect(dxi.d_dc); - - if (!smb_locate_dc(dom, kpasswd_srv, &dxi)) { - if (!smb_locate_dc(di->di_fqname, "", &dxi)) { - smb_ipc_commit(); - return (B_FALSE); - } - } - } - - smb_ipc_commit(); - if (mlsvc_netlogon(dxi.d_dc, di->di_nbname)) { - syslog(LOG_NOTICE, - "failed to establish NETLOGON credential chain"); - return (B_TRUE); - } else { - if (new_domain) { - smb_config_setdomaininfo(di->di_nbname, di->di_fqname, - di->di_sid, - di->di_u.di_dns.ddi_forest, - di->di_u.di_dns.ddi_guid); - (void) smb_config_setstr(SMB_CI_KPASSWD_DOMAIN, ""); - } - } - - return (new_domain); -} - -/* - * Retrieve the kpasswd server from krb5.conf. - * - * Initialization of the locate dc thread. - * Returns 0 on success, an error number if thread creation fails. - */ -static int -smbd_get_kpasswd_srv(char *srv, size_t len) -{ - FILE *fp; - static char buf[512]; - char *p; - - *srv = '\0'; - p = getenv("KRB5_CONFIG"); - if (p == NULL || *p == '\0') - p = "/etc/krb5/krb5.conf"; - - if ((fp = fopen(p, "r")) == NULL) - return (-1); - - while (fgets(buf, sizeof (buf), fp)) { - - /* Weed out any comment text */ - (void) trim_whitespace(buf); - if (*buf == '#') - continue; - - if ((p = strstr(buf, "kpasswd_server")) != NULL) { - if ((p = strchr(p, '=')) != NULL) { - (void) trim_whitespace(++p); - (void) strlcpy(srv, p, len); - } - break; - } - } - - - (void) fclose(fp); - return ((*srv == '\0') ? -1 : 0); -} - static uint32_t smbd_join_workgroup(smb_joininfo_t *info) { @@ -387,11 +243,10 @@ smbd_join_workgroup(smb_joininfo_t *info) static uint32_t smbd_join_domain(smb_joininfo_t *info) { - uint32_t status; - unsigned char passwd_hash[SMBAUTH_HASH_SZ]; - char dc[MAXHOSTNAMELEN]; + static unsigned char zero_hash[SMBAUTH_HASH_SZ]; smb_domainex_t dxi; smb_domain_t *di; + uint32_t status; /* * Ensure that any previous membership of this domain has @@ -399,43 +254,50 @@ smbd_join_domain(smb_joininfo_t *info) * will ensure that we don't attempt a NETLOGON_SAMLOGON * when attempting to find the PDC. */ - (void) smb_config_setbool(SMB_CI_DOMAIN_MEMB, B_FALSE); - if (smb_auth_ntlm_hash(info->domain_passwd, passwd_hash) - != SMBAUTH_SUCCESS) { - syslog(LOG_ERR, "smbd: could not compute ntlm hash for '%s'", - info->domain_username); - return (NT_STATUS_INTERNAL_ERROR); - } + /* Clear DNS local (ADS) lookup cache too. */ + smb_ads_refresh(); - smb_ipc_set(info->domain_username, passwd_hash); + /* + * Use a NULL session while searching for a DC, and + * while getting information about the domain. + */ + smb_ipc_set(MLSVC_ANON_USER, zero_hash); + + if (!smb_locate_dc(info->domain_name, "", &dxi)) { + syslog(LOG_ERR, "smbd: failed locating " + "domain controller for %s", + info->domain_name); + status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + goto errout; + } - (void) smbd_get_kpasswd_srv(dc, sizeof (dc)); /* info->domain_name could either be NetBIOS domain name or FQDN */ - if (smb_locate_dc(info->domain_name, dc, &dxi)) { - status = mlsvc_join(&dxi, info->domain_username, - info->domain_passwd); - - if (status == NT_STATUS_SUCCESS) { - di = &dxi.d_primary; - smbd_set_secmode(SMB_SECMODE_DOMAIN); - smb_config_setdomaininfo(di->di_nbname, di->di_fqname, - di->di_sid, - di->di_u.di_dns.ddi_forest, - di->di_u.di_dns.ddi_guid); - smb_ipc_commit(); - return (status); - } - - smb_ipc_rollback(); + status = mlsvc_join(&dxi, info->domain_username, info->domain_passwd); + if (status != NT_STATUS_SUCCESS) { syslog(LOG_ERR, "smbd: failed joining %s (%s)", info->domain_name, xlate_nt_status(status)); - return (status); + goto errout; } + /* + * Success! + * + * Strange, mlsvc_join does some of the work to + * save the config, then the rest happens here. + * Todo: Do the config update all in one place. + */ + di = &dxi.d_primary; + smbd_set_secmode(SMB_SECMODE_DOMAIN); + smb_config_setdomaininfo(di->di_nbname, di->di_fqname, + di->di_sid, + di->di_u.di_dns.ddi_forest, + di->di_u.di_dns.ddi_guid); + smb_ipc_commit(); + return (status); + +errout: smb_ipc_rollback(); - syslog(LOG_ERR, "smbd: failed locating domain controller for %s", - info->domain_name); - return (NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND); + return (status); } diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c index 4228f5c50a..a2828db3e9 100644 --- a/usr/src/cmd/zfs/zfs_main.c +++ b/usr/src/cmd/zfs/zfs_main.c @@ -63,6 +63,7 @@ #include <libuutil.h> #include <aclutils.h> #include <directory.h> +#include <idmap.h> #include "zfs_iter.h" #include "zfs_util.h" @@ -2439,9 +2440,8 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space) /* SMB */ char sid[ZFS_MAXNAMELEN + 32]; uid_t id; - uint64_t classes; int err; - directory_error_t e; + int flag = IDMAP_REQ_FLG_USE_CACHE; smbentity = B_TRUE; @@ -2458,10 +2458,13 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space) if (err == 0) { rid = id; if (!cb->cb_sid2posix) { - e = directory_name_from_sid(NULL, sid, &name, - &classes); - if (e != NULL) - directory_error_free(e); + if (type == USTYPE_SMB_USR) { + (void) idmap_getwinnamebyuid(rid, flag, + &name, NULL); + } else { + (void) idmap_getwinnamebygid(rid, flag, + &name, NULL); + } if (name == NULL) name = sid; } diff --git a/usr/src/lib/libidmap/common/idmap.h b/usr/src/lib/libidmap/common/idmap.h index 3a3af0d32c..01dce38944 100644 --- a/usr/src/lib/libidmap/common/idmap.h +++ b/usr/src/lib/libidmap/common/idmap.h @@ -113,6 +113,9 @@ extern idmap_stat idmap_getwinnamebyuid(uid_t, int, char **, char **); /* Given GID, get Windows name */ extern idmap_stat idmap_getwinnamebygid(gid_t, int, char **, char **); +/* Given PID, get Windows name */ +extern idmap_stat idmap_getwinnamebypid(uid_t, int, int, char **, char **); + /* Given Windows name, get UID */ extern idmap_stat idmap_getuidbywinname(const char *, const char *, int, uid_t *); diff --git a/usr/src/lib/libidmap/common/idmap_api.c b/usr/src/lib/libidmap/common/idmap_api.c index 36aba7b5f2..315c01a73c 100644 --- a/usr/src/lib/libidmap/common/idmap_api.c +++ b/usr/src/lib/libidmap/common/idmap_api.c @@ -2173,7 +2173,7 @@ idmap_getgidbywinname(const char *name, const char *domain, int flag, /* * Get winname given pid */ -static idmap_retcode +idmap_stat idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name, char **domain) { diff --git a/usr/src/lib/libidmap/common/mapfile-vers b/usr/src/lib/libidmap/common/mapfile-vers index fba4b644ef..4a6968ce49 100644 --- a/usr/src/lib/libidmap/common/mapfile-vers +++ b/usr/src/lib/libidmap/common/mapfile-vers @@ -83,6 +83,7 @@ SYMBOL_VERSION SUNWprivate { idmap_getgidbywinname; idmap_getuidbywinname; idmap_getwinnamebygid; + idmap_getwinnamebypid; idmap_getwinnamebyuid; idmap_how_clear; idmap_info_free; diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 1172abc647..f2dd13f1af 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -2577,7 +2577,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned, boolean_t isuser; domain[0] = '\0'; - + *ridp = 0; /* Figure out the property type ({user|group}{quota|space}) */ for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) { if (strncmp(propname, zfs_userquota_prop_prefixes[type], @@ -2598,35 +2598,61 @@ userquota_propname_decode(const char *propname, boolean_t zoned, * It's a SID name (eg "user@domain") that needs to be * turned into S-1-domainID-RID. */ - directory_error_t e; + int flag = 0; + idmap_stat stat, map_stat; + uid_t pid; + idmap_rid_t rid; + idmap_get_handle_t *gh = NULL; + + stat = idmap_get_create(&gh); + if (stat != IDMAP_SUCCESS) { + idmap_get_destroy(gh); + return (ENOMEM); + } if (zoned && getzoneid() == GLOBAL_ZONEID) return (ENOENT); if (isuser) { - e = directory_sid_from_user_name(NULL, - cp, &numericsid); + stat = idmap_getuidbywinname(cp, NULL, flag, &pid); + if (stat < 0) + return (ENOENT); + stat = idmap_get_sidbyuid(gh, pid, flag, &numericsid, + &rid, &map_stat); } else { - e = directory_sid_from_group_name(NULL, - cp, &numericsid); + stat = idmap_getgidbywinname(cp, NULL, flag, &pid); + if (stat < 0) + return (ENOENT); + stat = idmap_get_sidbygid(gh, pid, flag, &numericsid, + &rid, &map_stat); + } + if (stat < 0) { + idmap_get_destroy(gh); + return (ENOENT); } - if (e != NULL) { - directory_error_free(e); + stat = idmap_get_mappings(gh); + idmap_get_destroy(gh); + + if (stat < 0) { return (ENOENT); } if (numericsid == NULL) return (ENOENT); cp = numericsid; + *ridp = rid; /* will be further decoded below */ } if (strncmp(cp, "S-1-", 4) == 0) { /* It's a numeric SID (eg "S-1-234-567-89") */ (void) strlcpy(domain, cp, domainlen); - cp = strrchr(domain, '-'); - *cp = '\0'; - cp++; - errno = 0; - *ridp = strtoull(cp, &end, 10); + if (*ridp == 0) { + cp = strrchr(domain, '-'); + *cp = '\0'; + cp++; + *ridp = strtoull(cp, &end, 10); + } else { + end = ""; + } if (numericsid) { free(numericsid); numericsid = NULL; diff --git a/usr/src/lib/pysolaris/common/misc.c b/usr/src/lib/pysolaris/common/misc.c index 923cab445f..da7bb0075f 100644 --- a/usr/src/lib/pysolaris/common/misc.c +++ b/usr/src/lib/pysolaris/common/misc.c @@ -26,6 +26,7 @@ #include <Python.h> #include <zone.h> #include <libintl.h> +#include <idmap.h> #include <directory.h> #ifdef __lint @@ -62,36 +63,32 @@ py_sid_to_id(PyObject *self, PyObject *args) static PyObject * py_sid_to_name(PyObject *self, PyObject *args) { - int isuser; + int isuser, err, flag = IDMAP_REQ_FLG_USE_CACHE; char *name, *sid; - directory_error_t e; - uint64_t classes; + idmap_stat stat; + uid_t pid; PyObject *ret; if (!PyArg_ParseTuple(args, "si", &sid, &isuser)) return (NULL); - e = directory_name_from_sid(NULL, sid, &name, &classes); - if (e != NULL) { - directory_error_free(e); + + err = sid_to_id(sid, isuser, &pid); + if (err) { PyErr_SetString(PyExc_KeyError, sid); return (NULL); } - if (name == NULL) { + if (isuser) + stat = idmap_getwinnamebyuid(pid, flag, &name, NULL); + else + stat = idmap_getwinnamebygid(pid, flag, &name, NULL); + if (stat < 0) { PyErr_SetString(PyExc_KeyError, sid); return (NULL); } - if (isuser) { - if (!(classes & DIRECTORY_CLASS_USER)) { - free(name); - PyErr_SetString(PyExc_KeyError, sid); - return (NULL); - } - } else { - if (!(classes & DIRECTORY_CLASS_GROUP)) { - free(name); - PyErr_SetString(PyExc_KeyError, sid); - return (NULL); - } + + if (name == NULL) { + PyErr_SetString(PyExc_KeyError, sid); + return (NULL); } ret = PyString_FromString(name); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c index df29495ed1..043ee29549 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -88,7 +89,8 @@ static void lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *, * * On success 0 is returned. Otherwise a -ve error code. */ -int lsar_open(char *server, char *domain, char *username, +int +lsar_open(char *server, char *domain, char *username, mlsvc_handle_t *domain_handle) { if (server == NULL || domain == NULL) @@ -109,11 +111,6 @@ int lsar_open(char *server, char *domain, char *username, * function via lsar_open to ensure that the appropriate connection is * in place. * - * I'm not sure if it makes a difference whether we use GENERIC_EXECUTE - * or STANDARD_RIGHTS_EXECUTE. For a long time I used the standard bit - * and then I added the generic bit while working on privileges because - * NT sets that bit. I don't think it matters. - * * Returns 0 on success. Otherwise non-zero to indicate a failure. */ int @@ -141,15 +138,7 @@ lsar_open_policy2(char *server, char *domain, char *username, (void) snprintf((char *)arg.servername, len, "\\\\%s", server); arg.attributes.length = sizeof (struct mslsa_object_attributes); - - if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { - arg.desiredAccess = MAXIMUM_ALLOWED; - } else { - arg.desiredAccess = GENERIC_EXECUTE - | STANDARD_RIGHTS_EXECUTE - | POLICY_VIEW_LOCAL_INFORMATION - | POLICY_LOOKUP_NAMES; - } + arg.desiredAccess = MAXIMUM_ALLOWED; if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) { ndr_rpc_unbind(lsa_handle); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h index 8a5d55785b..d693d8825c 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SMBSRV_MLSVC_H @@ -33,6 +34,7 @@ extern "C" { #endif int smb_dclocator_init(void); +void smbrdr_initialize(void); void dssetup_initialize(void); void srvsvc_initialize(void); void wkssvc_initialize(void); diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c index bbeb99630d..0a52a43e65 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c @@ -20,8 +20,8 @@ */ /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -49,27 +49,6 @@ #include <libsmbrdr.h> #include <mlsvc.h> -/* - * Server info cache entry expiration in seconds. - */ -#define NDR_SVINFO_TIMEOUT 1800 - -typedef struct ndr_svinfo { - list_node_t svi_lnd; - time_t svi_tcached; - char svi_server[MAXNAMELEN]; - char svi_domain[MAXNAMELEN]; - srvsvc_server_info_t svi_svinfo; -} ndr_svinfo_t; - -typedef struct ndr_svlist { - list_t svl_list; - mutex_t svl_mtx; - boolean_t svl_init; -} ndr_svlist_t; - -static ndr_svlist_t ndr_svlist; - static int ndr_xa_init(ndr_client_t *, ndr_xa_t *); static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *); static int ndr_xa_read(ndr_client_t *, ndr_xa_t *); @@ -77,53 +56,6 @@ static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *); static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *); static void ndr_xa_release(ndr_client_t *); -static int ndr_svinfo_lookup(char *, char *, srvsvc_server_info_t *); -static boolean_t ndr_svinfo_match(const char *, const char *, const - ndr_svinfo_t *); -static boolean_t ndr_svinfo_expired(ndr_svinfo_t *); - -/* - * Initialize the RPC client interface: create the server info cache. - */ -void -ndr_rpc_init(void) -{ - (void) mutex_lock(&ndr_svlist.svl_mtx); - - if (!ndr_svlist.svl_init) { - list_create(&ndr_svlist.svl_list, sizeof (ndr_svinfo_t), - offsetof(ndr_svinfo_t, svi_lnd)); - ndr_svlist.svl_init = B_TRUE; - } - - (void) mutex_unlock(&ndr_svlist.svl_mtx); -} - -/* - * Terminate the RPC client interface: flush and destroy the server info - * cache. - */ -void -ndr_rpc_fini(void) -{ - ndr_svinfo_t *svi; - - (void) mutex_lock(&ndr_svlist.svl_mtx); - - if (ndr_svlist.svl_init) { - while ((svi = list_head(&ndr_svlist.svl_list)) != NULL) { - list_remove(&ndr_svlist.svl_list, svi); - free(svi->svi_svinfo.sv_name); - free(svi->svi_svinfo.sv_comment); - free(svi); - } - - list_destroy(&ndr_svlist.svl_list); - ndr_svlist.svl_init = B_FALSE; - } - - (void) mutex_unlock(&ndr_svlist.svl_mtx); -} /* * This call must be made to initialize an RPC client structure and bind @@ -158,10 +90,9 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain, /* * Set the default based on the assumption that most - * servers will be Windows 2000 or later. - * Don't lookup the svinfo if this is a SRVSVC request - * because the SRVSVC is used to get the server info. - * None of the SRVSVC calls depend on the server info. + * servers will be Windows 2000 or later. This used to + * try to get the actual server version, but that RPC + * is not necessarily allowed anymore, so don't bother. */ bzero(&svinfo, sizeof (srvsvc_server_info_t)); svinfo.sv_platform_id = SV_PLATFORM_ID_NT; @@ -170,8 +101,12 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain, svinfo.sv_type = SV_TYPE_DEFAULT; svinfo.sv_os = NATIVE_OS_WIN2000; - if (strcasecmp(service, "SRVSVC") != 0) - (void) ndr_svinfo_lookup(server, domain, &svinfo); + /* + * Some callers pass this when they want a NULL session. + * Todo: have callers pass an empty string for that. + */ + if (strcmp(username, MLSVC_ANON_USER) == 0) + username = ""; /* * Setup smbfs library handle, authenticate, connect to @@ -180,9 +115,10 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain, * server, user, domain. */ if ((rc = smbrdr_ctx_new(&ctx, server, domain, username)) != 0) { - syslog(LOG_ERR, "ndr_rpc_bind: " - "smbrdr_ctx_new(S=%s, D=%s, U=%s), err=%d", - server, domain, username, rc); + syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new" + "(Srv=%s Dom=%s User=%s), %s (0x%x)", + server, domain, username, + xlate_nt_status(rc), rc); goto errout; } @@ -200,7 +136,7 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain, * Setup the RPC client handle. */ if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) - return (-1); + goto errout; bzero(clnt, sizeof (ndr_client_t)); clnt->handle = &handle->handle; @@ -623,107 +559,6 @@ ndr_xa_release(ndr_client_t *clnt) } } -/* - * Lookup platform, type and version information about a server. - * If the cache doesn't already contain the data, contact the server and - * cache the response before returning the server info to the caller. - * - * We don't provide the name or comment for now, which avoids the need - * to deal with unnecessary memory management. - */ -static int -ndr_svinfo_lookup(char *server, char *domain, srvsvc_server_info_t *svinfo) -{ - static boolean_t timechecked = B_FALSE; - ndr_svinfo_t *svi; - - (void) mutex_lock(&ndr_svlist.svl_mtx); - if (!ndr_svlist.svl_init) - return (-1); - - svi = list_head(&ndr_svlist.svl_list); - while (svi != NULL) { - if (ndr_svinfo_expired(svi)) { - svi = list_head(&ndr_svlist.svl_list); - continue; - } - - if (ndr_svinfo_match(server, domain, svi)) { - bcopy(&svi->svi_svinfo, svinfo, - sizeof (srvsvc_server_info_t)); - svinfo->sv_name = NULL; - svinfo->sv_comment = NULL; - (void) mutex_unlock(&ndr_svlist.svl_mtx); - return (0); - } - - svi = list_next(&ndr_svlist.svl_list, svi); - } - - if ((svi = malloc(sizeof (ndr_svinfo_t))) == NULL) { - (void) mutex_unlock(&ndr_svlist.svl_mtx); - return (-1); - } - - if (srvsvc_net_server_getinfo(server, domain, &svi->svi_svinfo) < 0) { - (void) mutex_unlock(&ndr_svlist.svl_mtx); - free(svi); - return (-1); - } - - (void) time(&svi->svi_tcached); - (void) strlcpy(svi->svi_server, server, MAXNAMELEN); - (void) strlcpy(svi->svi_domain, domain, MAXNAMELEN); - list_insert_tail(&ndr_svlist.svl_list, svi); - bcopy(&svi->svi_svinfo, svinfo, sizeof (srvsvc_server_info_t)); - svinfo->sv_name = NULL; - svinfo->sv_comment = NULL; - - if (!timechecked) { - timechecked = B_TRUE; - ndr_srvsvc_timecheck(server, domain); - } - - (void) mutex_unlock(&ndr_svlist.svl_mtx); - return (0); -} - -static boolean_t -ndr_svinfo_match(const char *server, const char *domain, - const ndr_svinfo_t *svi) -{ - if ((smb_strcasecmp(server, svi->svi_server, 0) == 0) && - (smb_strcasecmp(domain, svi->svi_domain, 0) == 0)) { - return (B_TRUE); - } - - return (B_FALSE); -} - -/* - * If the server info in the cache has expired, discard it and return true. - * Otherwise return false. - * - * This is a private function to support ndr_svinfo_lookup() that assumes - * the list mutex is held. - */ -static boolean_t -ndr_svinfo_expired(ndr_svinfo_t *svi) -{ - time_t tnow; - - (void) time(&tnow); - - if (difftime(tnow, svi->svi_tcached) > NDR_SVINFO_TIMEOUT) { - list_remove(&ndr_svlist.svl_list, svi); - free(svi->svi_svinfo.sv_name); - free(svi->svi_svinfo.sv_comment); - free(svi); - return (B_TRUE); - } - - return (B_FALSE); -} /* * Compare the time here with the remote time on the server diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c index 32f87fbbe6..00040f5482 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 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #include <syslog.h> @@ -65,7 +65,7 @@ static pthread_t smb_dclocator_thr; static void *smb_ddiscover_service(void *); static void smb_ddiscover_main(char *, char *); -static boolean_t smb_ddiscover_dns(char *, char *, smb_domainex_t *); +static uint32_t smb_ddiscover_dns(char *, char *, smb_domainex_t *); static boolean_t smb_ddiscover_nbt(char *, char *, smb_domainex_t *); static boolean_t smb_ddiscover_domain_match(char *, char *, uint32_t); static uint32_t smb_ddiscover_qinfo(char *, char *, smb_domainex_t *); @@ -235,26 +235,27 @@ static void smb_ddiscover_main(char *domain, char *server) { smb_domainex_t dxi; - boolean_t discovered; + uint32_t status; bzero(&dxi, sizeof (smb_domainex_t)); if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS) return; - if (SMB_IS_FQDN(domain)) - discovered = smb_ddiscover_dns(domain, server, &dxi); - else - discovered = smb_ddiscover_nbt(domain, server, &dxi); + status = smb_ddiscover_dns(domain, server, &dxi); + if (status != 0 && !SMB_IS_FQDN(domain)) { + if (smb_ddiscover_nbt(domain, server, &dxi)) + status = 0; + } - if (discovered) + if (status == 0) smb_domain_update(&dxi); smb_domain_end_update(); smb_domainex_free(&dxi); - if (discovered) + if (status == 0) smb_domain_save(); } @@ -262,16 +263,16 @@ smb_ddiscover_main(char *domain, char *server) * Discovers a DC for the specified domain via DNS. If a DC is found * primary and trusted domains information will be queried. */ -static boolean_t +static uint32_t smb_ddiscover_dns(char *domain, char *server, smb_domainex_t *dxi) { uint32_t status; if (!smb_ads_lookup_msdcs(domain, server, dxi->d_dc, MAXHOSTNAMELEN)) - return (B_FALSE); + return (NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND); status = smb_ddiscover_qinfo(domain, dxi->d_dc, dxi); - return (status == NT_STATUS_SUCCESS); + return (status); } /* diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c index f1d11a6cfe..0fbe2a6890 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 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #include <sys/errno.h> @@ -60,7 +60,7 @@ mlsvc_init(void) return (rc); smb_quota_init(); - ndr_rpc_init(); + smbrdr_initialize(); srvsvc_initialize(); wkssvc_initialize(); lsarpc_initialize(); @@ -89,7 +89,6 @@ mlsvc_fini(void) svcctl_finalize(); logr_finalize(); netdfs_finalize(); - ndr_rpc_fini(); smb_quota_fini(); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c index e9ff66635b..45973ab820 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* @@ -40,19 +40,26 @@ #include <smbsrv/libsmb.h> #include <smbsrv/libsmbns.h> #include <smbsrv/libmlsvc.h> +#include <smbsrv/ntaccess.h> #include <smbsrv/smbinfo.h> #include <libsmbrdr.h> #include <lsalib.h> #include <samlib.h> #include <smbsrv/netrauth.h> -/* Domain join support (using MS-RPC) */ -static boolean_t mlsvc_ntjoin_support = B_FALSE; - extern int netr_open(char *, char *, mlsvc_handle_t *); extern int netr_close(mlsvc_handle_t *); extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD); +static DWORD +mlsvc_join_rpc(smb_domainex_t *dxi, + char *admin_user, char *admin_pw, + char *machine_name, char *machine_pw); +static DWORD +mlsvc_join_noauth(smb_domainex_t *dxi, + char *machine_name, char *machine_pw); + + DWORD mlsvc_netlogon(char *server, char *domain) { @@ -66,79 +73,268 @@ mlsvc_netlogon(char *server, char *domain) "credential chain"); (void) netr_close(&netr_handle); } else { - status = NT_STATUS_OPEN_FAILED; + syslog(LOG_NOTICE, "Failed to connect to %s " + "for domain %s", server, domain); + status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } return (status); } /* - * Joins the specified domain by creating a machine account on - * the selected domain controller. + * Join the specified domain. The method varies depending on whether + * we're using "secure join" (using an administrative account to join) + * or "unsecure join" (using a pre-created machine account). In the + * latter case, the machine account is created "by hand" before this + * machine attempts to join, and we just change the password from the + * (weak) default password for a new machine account to a random one. * - * Disconnect any existing connection with the domain controller. - * This will ensure that no stale connection will be used, it will - * also pickup any configuration changes in either side by trying - * to establish a new connection. + * Note that the caller has already done "DC discovery" and passes the + * domain info. in the first arg. * * Returns NT status codes. */ DWORD -mlsvc_join(smb_domainex_t *dxi, char *user, char *plain_text) +mlsvc_join(smb_domainex_t *dxi, char *admin_user, char *admin_pw) { - int erc; + char machine_name[SMB_SAMACCT_MAXLEN]; + char machine_pw[NETR_MACHINE_ACCT_PASSWD_MAX]; + unsigned char passwd_hash[SMBAUTH_HASH_SZ]; + smb_domain_t *di = &dxi->d_primary; DWORD status; - char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX]; - smb_adjoin_status_t err; - smb_domain_t *domain; - - machine_passwd[0] = '\0'; + int rc; - domain = &dxi->d_primary; + /* + * Domain join support: AD (Kerberos+LDAP) or MS-RPC? + * Leave the AD code path disabled until it can be + * fixed up so that the SMB server is in complete + * control of which AD server we talk to. See: + * NX 12427 (Re-enable Kerberos+LDAP with...) + */ + boolean_t ads_enabled = smb_config_get_ads_enable(); - mlsvc_disconnect(dxi->d_dc); + if (smb_getsamaccount(machine_name, sizeof (machine_name)) != 0) + return (NT_STATUS_INTERNAL_ERROR); - erc = smbrdr_logon(dxi->d_dc, domain->di_nbname, user); + (void) smb_gen_random_passwd(machine_pw, sizeof (machine_pw)); - if (erc == AUTH_USER_GRANT) { - if (mlsvc_ntjoin_support == B_FALSE) { + /* + * A non-null user means we do "secure join". + */ + if (admin_user != NULL && admin_user[0] != '\0') { + /* + * Doing "secure join", so authenticate as the + * specified user (with admin. rights). + */ + (void) smb_auth_ntlm_hash(admin_pw, passwd_hash); + smb_ipc_set(admin_user, passwd_hash); - if ((err = smb_ads_join(domain->di_fqname, user, - plain_text, machine_passwd, - sizeof (machine_passwd))) == SMB_ADJOIN_SUCCESS) { - status = NT_STATUS_SUCCESS; - } else { + /* + * If enabled, try to join using AD Services. + * The ADS code needs work. Not enabled yet. + */ + status = NT_STATUS_UNSUCCESSFUL; + if (ads_enabled) { + smb_adjoin_status_t err; + err = smb_ads_join(di->di_fqname, + admin_user, admin_pw, machine_pw); + if (err != SMB_ADJOIN_SUCCESS) { smb_ads_join_errmsg(err); - status = NT_STATUS_UNSUCCESSFUL; - } - } else { - - status = sam_create_trust_account(dxi->d_dc, - domain->di_nbname); - if (status == NT_STATUS_SUCCESS) { - (void) smb_getnetbiosname(machine_passwd, - sizeof (machine_passwd)); - (void) smb_strlwr(machine_passwd); + } else { + status = NT_STATUS_SUCCESS; } } - if (status == NT_STATUS_SUCCESS) { - erc = smb_setdomainprops(NULL, dxi->d_dc, - machine_passwd); - if (erc != 0) { - syslog(LOG_NOTICE, - "Failed to update configuration"); - bzero(machine_passwd, sizeof (machine_passwd)); - return (NT_STATUS_UNSUCCESSFUL); - } - - status = mlsvc_netlogon(dxi->d_dc, domain->di_nbname); + /* + * If ADS was disabled or gave an error, + * fall-back and try to join using RPC. + */ + if (status != NT_STATUS_SUCCESS) { + status = mlsvc_join_rpc(dxi, + admin_user, admin_pw, + machine_name, machine_pw); } + } else { - status = NT_STATUS_LOGON_FAILURE; + /* + * Doing "Unsecure join" (pre-created account) + */ + bzero(passwd_hash, sizeof (passwd_hash)); + smb_ipc_set(MLSVC_ANON_USER, passwd_hash); + + status = mlsvc_join_noauth(dxi, machine_name, machine_pw); } - bzero(machine_passwd, sizeof (machine_passwd)); + if (status != NT_STATUS_SUCCESS) + goto out; + + /* + * Make sure we can authenticate using the + * (new, or updated) machine account. + */ + (void) smb_auth_ntlm_hash(machine_pw, passwd_hash); + smb_ipc_set(machine_name, passwd_hash); + rc = smbrdr_logon(dxi->d_dc, di->di_nbname, machine_name); + if (rc != 0) { + syslog(LOG_NOTICE, "Authenticate with " + "new/updated machine account: %s", + strerror(rc)); + status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto out; + } + + /* + * Store the new machine account password. + */ + rc = smb_setdomainprops(NULL, dxi->d_dc, machine_pw); + if (rc != 0) { + syslog(LOG_NOTICE, + "Failed to save machine account password"); + status = NT_STATUS_INTERNAL_DB_ERROR; + goto out; + } + + /* + * Update idmap config + */ + if (smb_config_set_idmap_domain(di->di_fqname) != 0) + syslog(LOG_NOTICE, "Failed to set idmap domain name"); + if (smb_config_refresh_idmap() != 0) + syslog(LOG_NOTICE, "Failed to refresh idmap service"); + + /* + * Note: The caller (smbd) saves the "secmode" and + * domain info (via smb_config_setdomaininfo) and + * and does smb_ipc_commit (or rollback). + */ + status = 0; + +out: + /* Avoid leaving cleartext passwords around. */ + bzero(machine_pw, sizeof (machine_pw)); + bzero(passwd_hash, sizeof (passwd_hash)); + + return (status); +} + +static DWORD +mlsvc_join_rpc(smb_domainex_t *dxi, + char *admin_user, char *admin_pw, + char *machine_name, char *machine_pw) +{ + mlsvc_handle_t samr_handle; + mlsvc_handle_t domain_handle; + mlsvc_handle_t user_handle; + smb_account_t ainfo; + char *server = dxi->d_dc; + smb_domain_t *di = &dxi->d_primary; + DWORD account_flags; + DWORD rid; + DWORD status; + int rc; + + /* Caller did smb_ipc_set() so we don't need the pw for now. */ + _NOTE(ARGUNUSED(admin_pw)); + + rc = samr_open(server, di->di_nbname, admin_user, + MAXIMUM_ALLOWED, &samr_handle); + if (rc != 0) { + syslog(LOG_NOTICE, "sam_connect to server %s failed", server); + return (RPC_NT_SERVER_UNAVAILABLE); + } + /* have samr_handle */ + + status = samr_open_domain(&samr_handle, MAXIMUM_ALLOWED, + (struct samr_sid *)di->di_binsid, &domain_handle); + if (status != NT_STATUS_SUCCESS) + goto out_samr_handle; + /* have domain_handle */ + + account_flags = SAMR_AF_WORKSTATION_TRUST_ACCOUNT; + status = samr_create_user(&domain_handle, machine_name, + account_flags, &rid, &user_handle); + if (status == NT_STATUS_USER_EXISTS) { + status = samr_lookup_domain_names(&domain_handle, + machine_name, &ainfo); + if (status != NT_STATUS_SUCCESS) + goto out_domain_handle; + status = samr_open_user(&domain_handle, MAXIMUM_ALLOWED, + ainfo.a_rid, &user_handle); + } + if (status != NT_STATUS_SUCCESS) { + syslog(LOG_NOTICE, + "Create or open machine account: %s", + xlate_nt_status(status)); + goto out_domain_handle; + } + + /* + * The account exists, and we have user_handle open + * on that account. Set the password and flags. + */ + + status = netr_set_user_password(&user_handle, machine_pw); + if (status != NT_STATUS_SUCCESS) { + syslog(LOG_NOTICE, + "Set machine account password: %s", + xlate_nt_status(status)); + goto out_user_handle; + } + + account_flags |= SAMR_AF_DONT_EXPIRE_PASSWD; + status = netr_set_user_control(&user_handle, account_flags); + if (status != NT_STATUS_SUCCESS) { + syslog(LOG_NOTICE, + "Set machine account control flags: %s", + xlate_nt_status(status)); + goto out_user_handle; + } + +out_user_handle: + (void) samr_close_handle(&user_handle); +out_domain_handle: + (void) samr_close_handle(&domain_handle); +out_samr_handle: + (void) samr_close_handle(&samr_handle); + + return (status); +} + +/* + * Doing "Unsecure join" (using a pre-created machine account). + * All we need to do is change the password from the default + * to a random string. + * + * Note: this is a work in progres. Nexenta issue 11960 + * (allow joining an AD domain using a pre-created computer account) + * It turns out that to change the machine account password, + * we need to use a different RPC call, performed over the + * NetLogon secure channel. (See netr_server_password_set2) + */ +static DWORD +mlsvc_join_noauth(smb_domainex_t *dxi, + char *machine_name, char *machine_pw) +{ + char old_pw[SMB_SAMACCT_MAXLEN]; + DWORD status; + + /* + * Compose the current (default) password for the + * pre-created machine account, which is just the + * account name in lower case, truncated to 14 + * characters. + */ + if (smb_gethostname(old_pw, sizeof (old_pw), SMB_CASE_LOWER) != 0) + return (NT_STATUS_INTERNAL_ERROR); + old_pw[14] = '\0'; + + status = netr_change_password(dxi->d_dc, machine_name, + old_pw, machine_pw); + if (status != NT_STATUS_SUCCESS) { + syslog(LOG_NOTICE, + "Change machine account password: %s", + xlate_nt_status(status)); + } return (status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c index 96fc566706..4b0224261b 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -104,6 +105,12 @@ netlogon_auth(char *server, mlsvc_handle_t *netr_handle, DWORD flags) if ((rc = netr_server_req_challenge(netr_handle, netr_info)) == 0) { rc = netr_server_authenticate2(netr_handle, netr_info); if (rc == 0) { + /* + * TODO: (later) When joining a domain using a + * pre-created machine account, should do: + * netr_server_password_set(&netr_handle, netr_info); + * Nexenta issue 11960 + */ smb_update_netlogon_seqnum(); netr_info->flags |= NETR_FLG_VALID; @@ -490,7 +497,7 @@ netr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) arg.servername = (unsigned char *)netr_info->server; arg.account_name = (unsigned char *)account_name; - arg.account_type = NETR_WKSTA_TRUST_ACCOUNT_TYPE; + arg.sec_chan_type = NETR_WKSTA_TRUST_ACCOUNT_TYPE; arg.hostname = (unsigned char *)netr_info->hostname; /* @@ -509,7 +516,7 @@ netr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info) return (-1); } - (void) memcpy(&arg.uas_new_password, &new_password, + (void) memcpy(&arg.owf_password, &new_password, NETR_OWF_PASSWORD_SZ); if (ndr_rpc_call(netr_handle, opnum, &arg) != 0) @@ -569,3 +576,8 @@ netr_gen_password(BYTE *session_key, BYTE *old_password, BYTE *new_password) NETR_DESKEY_LEN, &old_password[8], 8); return (rv); } + +/* + * Todo: need netr_server_password_set2() + * used by "unsecure join". (NX 11960) + */ diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c index 601283fa5e..1a2233ce39 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -28,6 +29,10 @@ * functions. */ +#include <sys/types.h> +#include <sys/isa_defs.h> +#include <sys/byteorder.h> + #include <alloca.h> #include <smbsrv/libsmb.h> @@ -36,128 +41,32 @@ #include <lsalib.h> #include <samlib.h> +#ifdef _LITTLE_ENDIAN +/* little-endian values on little-endian */ +#define htolel(x) ((uint32_t)(x)) +#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) +#endif /* (BYTE_ORDER == LITTLE_ENDIAN) */ + /* * Valid values for the OEM OWF password encryption. */ -#define SAM_PASSWORD_516 516 #define SAM_KEYLEN 16 -extern DWORD samr_set_user_info(mlsvc_handle_t *); -static struct samr_sid *sam_get_domain_sid(mlsvc_handle_t *, char *, char *); - -/* - * sam_create_trust_account - * - * Create a trust account for this system. - * - * SAMR_AF_WORKSTATION_TRUST_ACCOUNT: servers and workstations. - * SAMR_AF_SERVER_TRUST_ACCOUNT: domain controllers. - * - * Returns NT status codes. - */ -DWORD -sam_create_trust_account(char *server, char *domain) -{ - char account_name[SMB_SAMACCT_MAXLEN]; - DWORD status; - - if (smb_getsamaccount(account_name, SMB_SAMACCT_MAXLEN) != 0) - return (NT_STATUS_INTERNAL_ERROR); - - /* - * The trust account value here should match - * the value that will be used when the user - * information is set on this account. - */ - status = sam_create_account(server, domain, account_name, - SAMR_AF_WORKSTATION_TRUST_ACCOUNT); - - /* - * Based on network traces, a Windows 2000 client will - * always try to create the computer account first. - * If it existed, then check the user permission to join - * the domain. - */ - - if (status == NT_STATUS_USER_EXISTS) - status = sam_check_user(server, domain, account_name); - - return (status); -} +static void samr_fill_userpw(struct samr_user_password *, const char *); +static void samr_make_encrypted_password( + struct samr_encr_passwd *epw, + char *new_pw_clear, + uint8_t *crypt_key); /* - * sam_create_account - * - * Create the specified domain account in the SAM database on the - * domain controller. - * - * Account flags: - * SAMR_AF_NORMAL_ACCOUNT - * SAMR_AF_WORKSTATION_TRUST_ACCOUNT - * SAMR_AF_SERVER_TRUST_ACCOUNT - * - * Returns NT status codes. + * Todo: Implement "unjoin" domain, which would use the + * sam_remove_trust_account code below. */ -DWORD -sam_create_account(char *server, char *domain_name, char *account_name, - DWORD account_flags) -{ - mlsvc_handle_t samr_handle; - mlsvc_handle_t domain_handle; - mlsvc_handle_t user_handle; - union samr_user_info sui; - struct samr_sid *sid; - DWORD rid; - DWORD status; - int rc; - char user[SMB_USERNAME_MAXLEN]; - - smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); - - rc = samr_open(server, domain_name, user, SAM_CONNECT_CREATE_ACCOUNT, - &samr_handle); - - if (rc != 0) { - status = NT_STATUS_OPEN_FAILED; - smb_tracef("SamCreateAccount[%s\\%s]: %s", - domain_name, account_name, xlate_nt_status(status)); - return (status); - } - - sid = sam_get_domain_sid(&samr_handle, server, domain_name); - - status = samr_open_domain(&samr_handle, - SAM_DOMAIN_CREATE_ACCOUNT, sid, &domain_handle); - - if (status == NT_STATUS_SUCCESS) { - status = samr_create_user(&domain_handle, account_name, - account_flags, &rid, &user_handle); - - if (status == NT_STATUS_SUCCESS) { - (void) samr_query_user_info(&user_handle, - SAMR_QUERY_USER_CONTROL_INFO, &sui); - - (void) samr_get_user_pwinfo(&user_handle); - (void) samr_set_user_info(&user_handle); - (void) samr_close_handle(&user_handle); - } else if (status != NT_STATUS_USER_EXISTS) { - smb_tracef("SamCreateAccount[%s]: %s", - account_name, xlate_nt_status(status)); - } - - (void) samr_close_handle(&domain_handle); - } else { - smb_tracef("SamCreateAccount[%s]: open domain failed", - account_name); - status = (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - } - - (void) samr_close_handle(&samr_handle); - free(sid); - return (status); -} - /* * sam_remove_trust_account @@ -194,7 +103,7 @@ sam_delete_account(char *server, char *domain_name, char *account_name) mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; smb_account_t ainfo; - struct samr_sid *sid; + smb_sid_t *sid; DWORD access_mask; DWORD status; int rc; @@ -204,93 +113,44 @@ sam_delete_account(char *server, char *domain_name, char *account_name) rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, &samr_handle); - if (rc != 0) - return (NT_STATUS_OPEN_FAILED); - - sid = sam_get_domain_sid(&samr_handle, server, domain_name); - status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, - &domain_handle); - free(sid); - if (status != NT_STATUS_SUCCESS) { - (void) samr_close_handle(&samr_handle); - return (status); - } + return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); - if (status == NT_STATUS_SUCCESS) { - access_mask = STANDARD_RIGHTS_EXECUTE | DELETE; - status = samr_open_user(&domain_handle, access_mask, - ainfo.a_rid, &user_handle); - if (status == NT_STATUS_SUCCESS) { - if (samr_delete_user(&user_handle) != 0) - (void) samr_close_handle(&user_handle); - } + sid = samr_lookup_domain(&samr_handle, domain_name); + if (sid == NULL) { + status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto out_samr_hdl; } - (void) samr_close_handle(&domain_handle); - (void) samr_close_handle(&samr_handle); - return (status); -} - -/* - * sam_check_user - * - * Check to see if user have permission to access computer account. - * The user being checked is the specified user for joining the Solaris - * host to the domain. - */ -DWORD -sam_check_user(char *server, char *domain_name, char *account_name) -{ - mlsvc_handle_t samr_handle; - mlsvc_handle_t domain_handle; - mlsvc_handle_t user_handle; - smb_account_t ainfo; - struct samr_sid *sid; - DWORD access_mask; - DWORD status; - int rc; - char user[SMB_USERNAME_MAXLEN]; - - smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); - - rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, - &samr_handle); + status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, + (struct samr_sid *)sid, &domain_handle); + if (status != NT_STATUS_SUCCESS) + goto out_sid_ptr; - if (rc != 0) - return (NT_STATUS_OPEN_FAILED); + status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); + if (status != NT_STATUS_SUCCESS) + goto out_dom_hdl; - sid = sam_get_domain_sid(&samr_handle, server, domain_name); - status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, - &domain_handle); - free(sid); - if (status != NT_STATUS_SUCCESS) { - (void) samr_close_handle(&samr_handle); - return (status); - } + access_mask = STANDARD_RIGHTS_EXECUTE | DELETE; + status = samr_open_user(&domain_handle, access_mask, + ainfo.a_rid, &user_handle); + if (status != NT_STATUS_SUCCESS) + goto out_dom_hdl; - status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); - if (status == NT_STATUS_SUCCESS) { - /* - * Win2000 client uses this access mask. The - * following SAMR user specific rights bits are - * set: set password, set attributes, and get - * attributes. - */ - - access_mask = 0xb0; - status = samr_open_user(&domain_handle, - access_mask, ainfo.a_rid, &user_handle); - if (status == NT_STATUS_SUCCESS) - (void) samr_close_handle(&user_handle); - } + status = samr_delete_user(&user_handle); + (void) samr_close_handle(&user_handle); +out_dom_hdl: (void) samr_close_handle(&domain_handle); +out_sid_ptr: + free(sid); +out_samr_hdl: (void) samr_close_handle(&samr_handle); + return (status); } + /* * sam_lookup_name * @@ -372,54 +232,169 @@ sam_get_local_domains(char *server, char *domain_name) } /* - * sam_oem_password + * Set the account control flags on some account for which we + * have already opened a SAM handle with appropriate rights, + * passed in here as sam_handle, along with the new flags. + */ +DWORD +netr_set_user_control( + mlsvc_handle_t *user_handle, + DWORD UserAccountControl) +{ + struct samr_SetUserInfo16 info; + + info.UserAccountControl = UserAccountControl; + return (samr_set_user_info(user_handle, 16, &info)); +} + +/* + * Set the password on some account, for which we have already + * opened a SAM handle with appropriate rights, passed in here + * as sam_handle, along with the new password as cleartext. * - * Generate an OEM password. + * This builds a struct SAMPR_USER_INTERNAL5_INFORMATION [MS-SAMR] + * containing the new password, encrypted with our session key. */ -int -sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, - unsigned char *old_password) +DWORD +netr_set_user_password( + mlsvc_handle_t *user_handle, + char *new_pw_clear) +{ + unsigned char ssn_key[SMBAUTH_HASH_SZ]; + struct samr_SetUserInfo24 info; + + if (ndr_rpc_get_ssnkey(user_handle, ssn_key, SMBAUTH_HASH_SZ)) + return (NT_STATUS_INTERNAL_ERROR); + + (void) memset(&info, 0, sizeof (info)); + samr_make_encrypted_password(&info.encr_pw, new_pw_clear, ssn_key); + + /* Rather not leave the session key around. */ + (void) memset(ssn_key, 0, sizeof (ssn_key)); + + return (samr_set_user_info(user_handle, 24, &info)); +} + +/* + * Change a password like NetUserChangePassword(), + * but where we already know which AD server to use, + * so we don't request the domain name or search for + * an AD server for that domain here. + */ +DWORD +netr_change_password( + char *server, + char *account, + char *old_pw_clear, + char *new_pw_clear) { - smb_wchar_t *unicode_password; - int length; + struct samr_encr_passwd epw; + struct samr_encr_hash old_hash; + uint8_t old_nt_hash[SAMR_PWHASH_LEN]; + uint8_t new_nt_hash[SAMR_PWHASH_LEN]; + mlsvc_handle_t handle; + DWORD rc; + + /* + * Create an RPC handle to this server, bound to SAMR. + */ + rc = ndr_rpc_bind(&handle, server, "", "", "SAMR"); + if (rc) + return (RPC_NT_SERVER_UNAVAILABLE); + + /* + * Encrypt the new p/w (plus random filler) with the + * old password, and send the old p/w encrypted with + * the new p/w hash to prove we know the old p/w. + * Details: [MS-SAMR 3.1.5.10.3] + */ + (void) smb_auth_ntlm_hash(old_pw_clear, old_nt_hash); + (void) smb_auth_ntlm_hash(new_pw_clear, new_nt_hash); + samr_make_encrypted_password(&epw, new_pw_clear, old_nt_hash); -#ifdef PBSHORTCUT - assert(sizeof (oem_password_t) == SAM_PASSWORD_516); -#endif /* PBSHORTCUT */ + (void) smb_auth_DES(old_hash.data, SAMR_PWHASH_LEN, + new_nt_hash, 14, /* key */ + old_nt_hash, SAMR_PWHASH_LEN); - length = strlen((char const *)new_password); - unicode_password = alloca((length + 1) * sizeof (smb_wchar_t)); + /* + * Finally, ready to try the OtW call. + */ + rc = samr_change_password( + &handle, server, account, + &epw, &old_hash); - length = smb_auth_qnd_unicode((unsigned short *)unicode_password, - (char *)new_password, length); - oem_password->length = length; + /* Avoid leaving cleartext (or equivalent) around. */ + (void) memset(old_nt_hash, 0, sizeof (old_nt_hash)); + (void) memset(new_nt_hash, 0, sizeof (new_nt_hash)); - (void) memcpy(&oem_password->data[512 - length], - unicode_password, length); + ndr_rpc_unbind(&handle); + return (rc); +} - rand_hash((unsigned char *)oem_password, sizeof (oem_password_t), - old_password, SAM_KEYLEN); +/* + * Build an encrypted password, as used by samr_set_user_info + * and samr_change_password. Note: This builds the unencrypted + * form in one union arm, and encrypts it in the other union arm. + */ +void +samr_make_encrypted_password( + struct samr_encr_passwd *epw, + char *new_pw_clear, + uint8_t *crypt_key) +{ + union { + struct samr_user_password u; + struct samr_encr_passwd e; + } pwu; + + samr_fill_userpw(&pwu.u, new_pw_clear); - return (0); + (void) smb_auth_RC4(pwu.e.data, sizeof (pwu.e.data), + crypt_key, SAMR_PWHASH_LEN, + pwu.e.data, sizeof (pwu.e.data)); + + (void) memcpy(epw->data, pwu.e.data, sizeof (pwu.e.data)); + (void) memset(pwu.e.data, 0, sizeof (pwu.e.data)); } -static struct samr_sid * -sam_get_domain_sid(mlsvc_handle_t *samr_handle, char *server, char *domain_name) +/* + * This fills in a samr_user_password (a.k.a. SAMPR_USER_PASSWORD + * in the MS Net API) which has the new password "right justified" + * in the buffer, and any space on the left filled with random junk + * to improve the quality of the encryption that is subsequently + * applied to this buffer before it goes over the wire. + */ +static void +samr_fill_userpw(struct samr_user_password *upw, const char *new_pw) { - smb_sid_t *sid = NULL; - smb_domainex_t domain; - - if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) { - if (!smb_domain_getinfo(&domain)) { - if (lsa_query_account_domain_info(server, domain_name, - &domain.d_primary) != NT_STATUS_SUCCESS) - return (NULL); - } - - sid = smb_sid_fromstr(domain.d_primary.di_sid); - } else { - sid = samr_lookup_domain(samr_handle, domain_name); - } + smb_wchar_t *pbuf; + uint32_t pwlen_bytes; + size_t pwlen_wchars; + + /* + * First fill the whole buffer with the random junk. + * (Slightly less random when debugging:) + */ +#ifdef DEBUG + (void) memset(upw->Buffer, '*', sizeof (upw->Buffer)); +#else + randomize((char *)upw->Buffer, sizeof (upw->Buffer)); +#endif + + /* + * Now overwrite the last pwlen characters of + * that buffer with the password, and set the + * length field so the receiving end knows where + * the junk ends and the real password starts. + */ + pwlen_wchars = smb_wcequiv_strlen(new_pw) / 2; + if (pwlen_wchars > SAMR_USER_PWLEN) + pwlen_wchars = SAMR_USER_PWLEN; + pwlen_bytes = pwlen_wchars * 2; + + pbuf = &upw->Buffer[SAMR_USER_PWLEN - pwlen_wchars]; + (void) smb_mbstowcs(pbuf, new_pw, pwlen_wchars); - return ((struct samr_sid *)sid); + /* Yes, this is in Bytes, not wchars. */ + upw->Length = htolel(pwlen_bytes); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.h b/usr/src/lib/smbsrv/libmlsvc/common/samlib.h index 3a3932e40f..7e8e1a458d 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.h +++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.h @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SAMLIB_H @@ -71,9 +72,9 @@ DWORD sam_check_user(char *, char *, char *); /* * samr_open.c */ -int samr_open(char *, char *, char *, DWORD, mlsvc_handle_t *); -int samr_connect(char *, char *, char *, DWORD, mlsvc_handle_t *); -int samr_close_handle(mlsvc_handle_t *); +DWORD samr_open(char *, char *, char *, DWORD, mlsvc_handle_t *); +DWORD samr_connect(char *, char *, char *, DWORD, mlsvc_handle_t *); +void samr_close_handle(mlsvc_handle_t *); DWORD samr_open_domain(mlsvc_handle_t *, DWORD, struct samr_sid *, mlsvc_handle_t *); DWORD samr_open_user(mlsvc_handle_t *, DWORD, DWORD, mlsvc_handle_t *); @@ -112,7 +113,7 @@ union samr_user_info { } info9; struct info16 { - DWORD unknown; + DWORD acct_ctrl; } info16; }; @@ -120,16 +121,39 @@ union samr_user_info { smb_sid_t *samr_lookup_domain(mlsvc_handle_t *, char *); DWORD samr_enum_local_domains(mlsvc_handle_t *); uint32_t samr_lookup_domain_names(mlsvc_handle_t *, char *, smb_account_t *); -int samr_query_user_info(mlsvc_handle_t *, WORD, union samr_user_info *); +DWORD samr_query_user_info(mlsvc_handle_t *, WORD, union samr_user_info *); DWORD samr_get_user_pwinfo(mlsvc_handle_t *); -typedef struct oem_password { - BYTE data[512]; - DWORD length; -} oem_password_t; - - -int sam_oem_password(oem_password_t *, unsigned char *, unsigned char *); +DWORD +samr_change_password( + mlsvc_handle_t *handle, + char *server, + char *account, + struct samr_encr_passwd *newpw, + struct samr_encr_hash *oldpw); + +DWORD +samr_set_user_info( + mlsvc_handle_t *user_handle, + int info_level, + void *info_buf); + +DWORD +netr_set_user_control( + mlsvc_handle_t *user_handle, + DWORD UserAccountControl); + +DWORD +netr_set_user_password( + mlsvc_handle_t *user_handle, + char *new_pw_clear); + +DWORD +netr_change_password( + char *server, + char *account, + char *old_password, + char *new_password); #ifdef __cplusplus } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c index e19d1dfb03..fc2956f226 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -51,8 +52,6 @@ #include <smbsrv/smb_sid.h> #include <samlib.h> -/*LINTED E_STATIC_UNUSED*/ -static DWORD samr_connect1(char *, char *, char *, DWORD, mlsvc_handle_t *); static DWORD samr_connect2(char *, char *, char *, DWORD, mlsvc_handle_t *); static DWORD samr_connect4(char *, char *, char *, DWORD, mlsvc_handle_t *); static DWORD samr_connect5(char *, char *, char *, DWORD, mlsvc_handle_t *); @@ -62,9 +61,6 @@ typedef DWORD (*samr_connop_t)(char *, char *, char *, DWORD, static int samr_setup_user_info(WORD, struct samr_QueryUserInfo *, union samr_user_info *); -static void samr_set_user_unknowns(struct samr_SetUserInfo23 *); -static void samr_set_user_logon_hours(struct samr_SetUserInfo *); -static int samr_set_user_password(unsigned char *, BYTE *); /* * samr_open @@ -78,17 +74,16 @@ static int samr_set_user_password(unsigned char *, BYTE *); * * On success 0 is returned. Otherwise a -ve error code. */ -int +DWORD samr_open(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { smb_domainex_t di; - int rc; + DWORD status; if (server == NULL || domain == NULL) { if (!smb_domain_getinfo(&di)) - return (-1); - + return (NT_STATUS_INTERNAL_ERROR); server = di.d_dc; domain = di.d_primary.di_nbname; } @@ -96,8 +91,10 @@ samr_open(char *server, char *domain, char *username, DWORD access_mask, if (username == NULL) username = MLSVC_ANON_USER; - rc = samr_connect(server, domain, username, access_mask, samr_handle); - return (rc); + status = samr_connect(server, domain, username, access_mask, + samr_handle); + + return (status); } @@ -116,7 +113,7 @@ samr_open(char *server, char *domain, char *username, DWORD access_mask, * something other than an RPC protocol error. We don't use the original * connect call because all supported servers should support SamrConnect2. */ -int +DWORD samr_connect(char *server, char *domain, char *username, DWORD access_mask, mlsvc_handle_t *samr_handle) { @@ -130,60 +127,19 @@ samr_connect(char *server, char *domain, char *username, DWORD access_mask, DWORD status; int i; - if (ndr_rpc_bind(samr_handle, server, domain, username, "SAMR") < 0) - return (-1); + status = ndr_rpc_bind(samr_handle, server, domain, username, "SAMR"); + if (status) + return (status); for (i = 0; i < n_op; ++i) { status = (*samr_connop[i])(server, domain, username, access_mask, samr_handle); if (status == NT_STATUS_SUCCESS) - return (0); + return (status); } ndr_rpc_unbind(samr_handle); - return (-1); -} - -/* - * samr_connect1 - * - * Original SAMR connect call; probably used on Windows NT 3.51. - * Windows 95 uses this call with the srvmgr tools update. - * Servername appears to be a dword rather than a string. - * The first word contains '\' and the second word contains 0x001, - * (which is probably uninitialized junk: 0x0001005c. - */ -/*ARGSUSED*/ -static DWORD -samr_connect1(char *server, char *domain, char *username, DWORD access_mask, - mlsvc_handle_t *samr_handle) -{ - struct samr_Connect arg; - int opnum; - DWORD status; - - bzero(&arg, sizeof (struct samr_Connect)); - opnum = SAMR_OPNUM_Connect; - status = NT_STATUS_SUCCESS; - - arg.servername = ndr_rpc_malloc(samr_handle, sizeof (DWORD)); - *(arg.servername) = 0x0001005c; - arg.access_mask = access_mask; - - if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) { - status = NT_STATUS_UNSUCCESSFUL; - } else if (arg.status != 0) { - status = NT_SC_VALUE(arg.status); - } else { - (void) memcpy(&samr_handle->handle, &arg.handle, - sizeof (ndr_hdid_t)); - - if (ndr_is_null_handle(samr_handle)) - status = NT_STATUS_INVALID_HANDLE; - } - - ndr_rpc_release(samr_handle); return (status); } @@ -293,23 +249,14 @@ samr_connect5(char *server, char *domain, char *username, DWORD access_mask, int len; int opnum; DWORD status; - smb_domainex_t dinfo; bzero(&arg, sizeof (struct samr_Connect5)); opnum = SAMR_OPNUM_Connect5; status = NT_STATUS_SUCCESS; - if (!smb_domain_getinfo(&dinfo)) - return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); - - len = strlen(server) + strlen(dinfo.d_primary.di_fqname) + 4; + len = strlen(server) + 4; arg.servername = ndr_rpc_malloc(samr_handle, len); - - if (*dinfo.d_primary.di_fqname != '\0') - (void) snprintf((char *)arg.servername, len, "\\\\%s.%s", - server, dinfo.d_primary.di_fqname); - else - (void) snprintf((char *)arg.servername, len, "\\\\%s", server); + (void) snprintf((char *)arg.servername, len, "\\\\%s", server); arg.access_mask = SAM_ENUM_LOCAL_DOMAIN; arg.unknown2_00000001 = 0x00000001; @@ -342,14 +289,14 @@ samr_connect5(char *server, char *domain, char *username, DWORD access_mask, * If the handle being closed is the top level connect handle, we unbind. * Then we zero out the handle to invalidate it. */ -int +void samr_close_handle(mlsvc_handle_t *samr_handle) { struct samr_CloseHandle arg; int opnum; if (ndr_is_null_handle(samr_handle)) - return (-1); + return; opnum = SAMR_OPNUM_CloseHandle; bzero(&arg, sizeof (struct samr_CloseHandle)); @@ -362,7 +309,6 @@ samr_close_handle(mlsvc_handle_t *samr_handle) ndr_rpc_unbind(samr_handle); bzero(samr_handle, sizeof (mlsvc_handle_t)); - return (0); } /* @@ -591,8 +537,8 @@ samr_create_user(mlsvc_handle_t *domain_handle, char *username, status = NT_SC_VALUE(arg.status); if (status != NT_STATUS_USER_EXISTS) { - smb_tracef("SamrCreateUser[%s]: %s", username, - xlate_nt_status(status)); + smb_tracef("SamrCreateUser[%s]: %s", + username, xlate_nt_status(status)); } } else { ndr_inherit_handle(user_handle, domain_handle); @@ -637,8 +583,7 @@ samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name) sizeof (samr_handle_t)); length = smb_wcequiv_strlen(domain_name); - if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) - length += sizeof (smb_wchar_t); + length += sizeof (smb_wchar_t); arg.domain_name.length = length; arg.domain_name.allosize = length; @@ -727,8 +672,7 @@ samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, arg.total = 1; length = smb_wcequiv_strlen(name); - if (ndr_rpc_server_os(domain_handle) == NATIVE_OS_WIN2000) - length += sizeof (smb_wchar_t); + length += sizeof (smb_wchar_t); arg.name.length = length; arg.name.allosize = length; @@ -760,18 +704,17 @@ samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name, * Query information on a specific user. The handle must be a valid * user handle obtained via samr_open_user. * - * Returns 0 on success, otherwise returns -ve error code. + * Returns 0 on success, otherwise returns NT status code. */ -int +DWORD samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value, union samr_user_info *user_info) { struct samr_QueryUserInfo arg; int opnum; - int rc; if (ndr_is_null_handle(user_handle) || user_info == 0) - return (-1); + return (NT_STATUS_INTERNAL_ERROR); opnum = SAMR_OPNUM_QueryUserInfo; bzero(&arg, sizeof (struct samr_QueryUserInfo)); @@ -780,18 +723,13 @@ samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value, sizeof (samr_handle_t)); arg.switch_value = switch_value; - if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { - ndr_rpc_release(user_handle); - return (-1); - } + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) + arg.status = RPC_NT_CALL_FAILED; - if (arg.status != 0) - rc = -1; - else - rc = samr_setup_user_info(switch_value, &arg, user_info); + if (arg.status == 0) + (void) samr_setup_user_info(switch_value, &arg, user_info); - ndr_rpc_release(user_handle); - return (rc); + return (arg.status); } /* @@ -846,6 +784,8 @@ samr_setup_user_info(WORD switch_value, return (0); case 16: + user_info->info16.acct_ctrl = + arg->ru.info16.UserAccountControl; return (0); default: @@ -945,6 +885,10 @@ samr_get_user_pwinfo(mlsvc_handle_t *user_handle) return (status); } +DECL_FIXUP_STRUCT(samr_SetUserInfo_u); +DECL_FIXUP_STRUCT(samr_SetUserInfo_s); +DECL_FIXUP_STRUCT(samr_SetUserInfo); + /* * samr_set_user_info * @@ -952,138 +896,129 @@ samr_get_user_pwinfo(mlsvc_handle_t *user_handle) * NT status codes observed so far: * NT_STATUS_WRONG_PASSWORD */ -/*ARGSUSED*/ DWORD -samr_set_user_info(mlsvc_handle_t *user_handle) +samr_set_user_info( + mlsvc_handle_t *user_handle, + int info_level, + void *info_buf) { - unsigned char ssn_key[SMBAUTH_SESSION_KEY_SZ]; struct samr_SetUserInfo arg; + uint16_t usize, tsize; int opnum; - DWORD status = 0; if (ndr_is_null_handle(user_handle)) - return (NT_STATUS_INVALID_PARAMETER); + return (NT_STATUS_INTERNAL_ERROR); - if (ndr_rpc_get_ssnkey(user_handle, ssn_key, sizeof (ssn_key))) - return (NT_STATUS_INVALID_PARAMETER); + /* + * Only support a few levels + * MS-SAMR: UserInternal4Information + */ + switch (info_level) { + case 16: /* samr_SetUserInfo16 */ + usize = sizeof (struct samr_SetUserInfo16); + break; + case 21: /* samr_SetUserInfo21 */ + usize = sizeof (struct samr_SetUserInfo21); + break; + case 23: /* samr_SetUserInfo23 */ + usize = sizeof (struct samr_SetUserInfo23); + break; + case 24: /* samr_SetUserInfo24 */ + usize = sizeof (struct samr_SetUserInfo24); + break; + default: + return (NT_STATUS_INVALID_LEVEL); + } + + /* + * OK, now this gets really ugly, because + * ndrgen doesn't do unions correctly. + */ + FIXUP_PDU_SIZE(samr_SetUserInfo_u, usize); + tsize = usize + (2 * sizeof (WORD)); + FIXUP_PDU_SIZE(samr_SetUserInfo_s, tsize); + tsize += sizeof (ndr_request_hdr_t) + sizeof (DWORD); + FIXUP_PDU_SIZE(samr_SetUserInfo, tsize); opnum = SAMR_OPNUM_SetUserInfo; - bzero(&arg, sizeof (struct samr_SetUserInfo)); + bzero(&arg, sizeof (arg)); (void) memcpy(&arg.user_handle, &user_handle->handle, sizeof (samr_handle_t)); + arg.info.info_level = info_level; + arg.info.switch_value = info_level; + (void) memcpy(&arg.info.ru, info_buf, usize); - arg.info.index = SAMR_SET_USER_INFO_23; - arg.info.switch_value = SAMR_SET_USER_INFO_23; - - samr_set_user_unknowns(&arg.info.ru.info23); - samr_set_user_logon_hours(&arg); - - if (samr_set_user_password(ssn_key, arg.info.ru.info23.password) < 0) - status = NT_STATUS_INTERNAL_ERROR; - - if (ndr_rpc_call(user_handle, opnum, &arg) != 0) { - status = NT_STATUS_INVALID_PARAMETER; - } else if (arg.status != 0) { + if (ndr_rpc_call(user_handle, opnum, &arg) != 0) + arg.status = RPC_NT_CALL_FAILED; + else if (arg.status != 0) ndr_rpc_status(user_handle, opnum, arg.status); - status = NT_SC_VALUE(arg.status); - } ndr_rpc_release(user_handle); - return (status); -} - -static void -samr_set_user_unknowns(struct samr_SetUserInfo23 *info) -{ - bzero(info, sizeof (struct samr_SetUserInfo23)); - - info->sd.length = 0; - info->sd.data = 0; - info->user_rid = 0; - info->group_rid = DOMAIN_GROUP_RID_USERS; - - /* - * The trust account value used here should probably - * match the one used to create the trust account. - */ - info->acct_info = SAMR_AF_WORKSTATION_TRUST_ACCOUNT; - info->flags = 0x09F827FA; + return (arg.status); } /* - * samr_set_user_logon_hours - * - * SamrSetUserInfo appears to contain some logon hours information, which - * looks like a varying, conformant array. The top level contains a value - * (units), which probably indicates the how to interpret the array. The - * array definition looks like it contains a maximum size, an initial - * offset and a bit length (units/8), followed by the bitmap. - * - * (info) - * +-------+ - * | units | - * +-------+ (hours) - * | hours |-->+-----------+ - * +-------+ | max_is | - * +-----------+ - * | first_is | - * +-----------+ - * | length_is | - * +------------------------+ - * | bitmap[length_is] | - * +---------+--------------+ - * - * 10080 minutes/week => 10080/8 = 1260 (0x04EC) bytes. - * 168 hours/week => 168/8 = 21 (0xA8) bytes. - * In the netmon examples seen so far, all bits are set to 1, i.e. - * an array containing 0xff. This is probably the default setting. - * - * ndrgen has a problem with complex [size_is] statements (length/8). - * So, for now, we fake it using two separate components. + * Client side wrapper for SamrUnicodeChangePasswordUser2 + * [MS-SAMR 3.1.5.10.3] */ -static void -samr_set_user_logon_hours(struct samr_SetUserInfo *sui) -{ - sui->logon_hours.size = SAMR_HOURS_MAX_SIZE; - sui->logon_hours.first = 0; - sui->logon_hours.length = SAMR_SET_USER_HOURS_SZ; - (void) memset(sui->logon_hours.bitmap, 0xFF, SAMR_SET_USER_HOURS_SZ); - - sui->info.ru.info23.logon_info.units = SAMR_HOURS_PER_WEEK; - sui->info.ru.info23.logon_info.hours = - (DWORD)(uintptr_t)sui->logon_hours.bitmap; -} -/* - * samr_set_user_password - * - * Set the initial password for the user. - * - * Returns 0 if everything goes well, -1 if there is trouble generating a - * key. - */ -static int -samr_set_user_password(unsigned char *nt_key, BYTE *oem_password) +DWORD +samr_change_password( + mlsvc_handle_t *handle, + char *server, + char *account, + struct samr_encr_passwd *newpw, + struct samr_encr_hash *oldpw) { - char hostname[NETBIOS_NAME_SZ]; + static struct samr_encr_passwd zero_newpw; + static struct samr_encr_hash zero_oldpw; + struct samr_ChangePasswordUser2 arg; + int opnum = SAMR_OPNUM_ChangePasswordUser2; + char *slashserver; + int len; - randomize((char *)oem_password, SAMR_SET_USER_DATA_SZ); + (void) memset(&arg, 0, sizeof (arg)); - /* - * The new password is going to be the NetBIOS name of the system - * in lower case. - */ - if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) - return (-1); + /* Need server name with slashes */ + len = 2 + strlen(server) + 1; + slashserver = ndr_rpc_malloc(handle, len); + if (slashserver == NULL) + return (NT_STATUS_NO_MEMORY); + (void) snprintf(slashserver, len, "\\\\%s", server); - (void) smb_strlwr(hostname); + arg.servername = ndr_rpc_malloc(handle, sizeof (samr_string_t)); + if (arg.servername == NULL) + return (NT_STATUS_NO_MEMORY); + len = smb_wcequiv_strlen(slashserver); + if (len < 1) + return (NT_STATUS_INVALID_PARAMETER); + len += 2; /* the WC null */ + arg.servername->length = len; + arg.servername->allosize = len; + arg.servername->str = (uint8_t *)slashserver; + + arg.username = ndr_rpc_malloc(handle, sizeof (samr_string_t)); + if (arg.username == NULL) + return (NT_STATUS_NO_MEMORY); + len = smb_wcequiv_strlen(account); + if (len < 1) + return (NT_STATUS_INVALID_PARAMETER); + len += 2; /* the WC null */ + arg.username->length = len; + arg.username->allosize = len; + arg.username->str = (uint8_t *)account; - /* - * Generate the OEM password from the hostname and the user session - * key(nt_key). - */ - /*LINTED E_BAD_PTR_CAST_ALIGN*/ - (void) sam_oem_password((oem_password_t *)oem_password, - (unsigned char *)hostname, nt_key); - return (0); + arg.nt_newpw = newpw; + arg.nt_oldpw = oldpw; + + arg.lm_newpw = &zero_newpw; + arg.lm_oldpw = &zero_oldpw; + + if (ndr_rpc_call(handle, opnum, &arg) != 0) + arg.status = RPC_NT_CALL_FAILED; + else if (arg.status != 0) + ndr_rpc_status(handle, opnum, arg.status); + + ndr_rpc_release(handle); + return (arg.status); } diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c index a057e922b7..8e0753c0e3 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -1141,15 +1142,15 @@ samr_s_CreateUser(void *arg, ndr_xa_t *mxa) } /* - * samr_s_ChangeUserPasswd + * samr_s_ChangePasswordUser2 */ /*ARGSUSED*/ static int -samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) +samr_s_ChangePasswordUser2(void *arg, ndr_xa_t *mxa) { - struct samr_ChangeUserPasswd *param = arg; + struct samr_ChangePasswordUser2 *param = arg; - bzero(param, sizeof (struct samr_ChangeUserPasswd)); + bzero(param, sizeof (*param)); param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); return (NDR_DRC_OK); } @@ -1860,7 +1861,7 @@ static ndr_stub_table_t samr_stub_table[] = { { samr_s_Connect2, SAMR_OPNUM_Connect2 }, { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, - { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, + { samr_s_ChangePasswordUser2, SAMR_OPNUM_ChangePasswordUser2 }, { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, { samr_s_Connect4, SAMR_OPNUM_Connect4 }, diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c b/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c index 746acdf413..ab127b6150 100644 --- a/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c +++ b/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c @@ -20,8 +20,8 @@ */ /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* @@ -44,6 +44,12 @@ #include <assert.h> +void +smbrdr_initialize(void) +{ + (void) smb_lib_init(); +} + /* * mlsvc_disconnect * @@ -79,11 +85,9 @@ smbrdr_logon(char *srv, char *dom, char *user) int err; err = smbrdr_ctx_new(&ctx, srv, dom, user); - if (err) { - return (-1); - } - smb_ctx_free(ctx); - return (AUTH_USER_GRANT); + if (err == 0) + smb_ctx_free(ctx); + return (err); } void @@ -111,12 +115,8 @@ smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server, assert(domain != NULL); assert(user != NULL); - /* Some callers pass this when they want a NULL session. */ - if (strcmp(user, "IPC$") == 0) - user = ""; - if ((err = smb_ctx_alloc(&ctx)) != 0) - return (err); + return (NT_STATUS_NO_MEMORY); /* * Set server, share, domain, user @@ -150,12 +150,18 @@ smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server, * Do lookup, connect, session setup, tree connect. * Or find and reuse a session/tree, if one exists. */ - if ((err = smb_ctx_resolve(ctx)) != 0) + if ((err = smb_ctx_resolve(ctx)) != 0) { + err = NT_STATUS_BAD_NETWORK_PATH; goto errout; - if ((err = smb_ctx_get_ssn(ctx)) != 0) + } + if ((err = smb_ctx_get_ssn(ctx)) != 0) { + err = NT_STATUS_NETWORK_ACCESS_DENIED; goto errout; - if ((err = smb_ctx_get_tree(ctx)) != 0) + } + if ((err = smb_ctx_get_tree(ctx)) != 0) { + err = NT_STATUS_BAD_NETWORK_NAME; goto errout; + } /* Success! */ *ctx_p = ctx; diff --git a/usr/src/lib/smbsrv/libsmb/Makefile.com b/usr/src/lib/smbsrv/libsmb/Makefile.com index dbf479e106..bc371d4807 100644 --- a/usr/src/lib/smbsrv/libsmb/Makefile.com +++ b/usr/src/lib/smbsrv/libsmb/Makefile.com @@ -20,6 +20,7 @@ # # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012 Nexenta Systems, Inc. All rights reserved. # LIBRARY= libsmb.a @@ -76,8 +77,9 @@ INCS += -I$(SRC)/common/smbsrv LINTCHECKFLAGS += -erroff=E_INCONS_ARG_DECL2 LDLIBS += $(MACH_LDLIBS) -LDLIBS += -lscf -lmd -luuid -lnsl -lpkcs11 -lsec -lsocket -lresolv -LDLIBS += -lidmap -lreparse -lnvpair -lcmdutils -lavl -lc +LDLIBS += -lscf -lmd -luuid -lpkcs11 -lcryptoutil +LDLIBS += -lsec -lidmap -lnsl -lsocket -lresolv +LDLIBS += -lreparse -lnvpair -lcmdutils -lavl -lc CPPFLAGS += $(INCS) -D_REENTRANT CERRWARN += -_gcc=-Wno-uninitialized CERRWARN += -_gcc=-Wno-char-subscripts diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h index 8a11384b61..31a5aeee2f 100644 --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBSMB_H @@ -189,6 +189,7 @@ extern int smb_config_setstr(smb_cfg_id_t, char *); extern int smb_config_setnum(smb_cfg_id_t, int64_t); extern int smb_config_setbool(smb_cfg_id_t, boolean_t); +extern boolean_t smb_config_get_ads_enable(void); extern uint8_t smb_config_get_fg_flag(void); extern char *smb_config_get_localsid(void); extern int smb_config_secmode_fromstr(char *); @@ -478,6 +479,8 @@ extern int smb_auth_hmac_md5(unsigned char *, int, unsigned char *, int, extern int smb_auth_DES(unsigned char *, int, unsigned char *, int, unsigned char *, int); +extern int smb_auth_RC4(unsigned char *, int, unsigned char *, int, + unsigned char *, int); extern int smb_auth_md4(unsigned char *, unsigned char *, int); extern int smb_auth_lm_hash(const char *, unsigned char *); @@ -497,6 +500,8 @@ boolean_t smb_auth_validate_lm(unsigned char *, uint32_t, smb_passwd_t *, boolean_t smb_auth_validate_nt(unsigned char *, uint32_t, smb_passwd_t *, unsigned char *, int, char *, char *, uchar_t *); +int smb_gen_random_passwd(char *passwd, size_t bufsz); + /* * SMB authenticated IPC */ diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers index 63f2543780..4d2fc95e9b 100644 --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers @@ -74,6 +74,7 @@ SYMBOL_VERSION SUNWprivate { smb_acl_sort; smb_acl_to_zfs; smb_auth_DES; + smb_auth_RC4; smb_auth_gen_session_key; smb_auth_hmac_md5; smb_auth_ntlm_hash; @@ -97,6 +98,7 @@ SYMBOL_VERSION SUNWprivate { smb_common_decode; smb_common_encode; smb_config_get; + smb_config_get_ads_enable; smb_config_get_execinfo; smb_config_get_fg_flag; smb_config_get_localsid; @@ -175,6 +177,7 @@ SYMBOL_VERSION SUNWprivate { smb_fsacl_free; smb_fssd_init; smb_fssd_term; + smb_gen_random_passwd; smb_get_dcinfo; smb_get_nameservers; smb_get_txid; diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_auth.c b/usr/src/lib/smbsrv/libsmb/common/smb_auth.c index b53d109ed7..9f4100e805 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_auth.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_auth.c @@ -21,15 +21,14 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #include <strings.h> #include <stdlib.h> #include <smbsrv/string.h> #include <smbsrv/libsmb.h> - -extern void randomize(char *data, unsigned len); -static uint64_t unix_micro_to_nt_time(struct timeval *unix_time); +#include <assert.h> /* * smb_auth_qnd_unicode @@ -145,15 +144,15 @@ int smb_auth_ntlm_hash(const char *password, unsigned char *hash) { smb_wchar_t *unicode_password; - int length; + int length, unicode_len; int rc; if (password == NULL || hash == NULL) return (SMBAUTH_FAILURE); length = strlen(password); - unicode_password = (smb_wchar_t *) - malloc((length + 1) * sizeof (smb_wchar_t)); + unicode_len = (length + 1) * sizeof (smb_wchar_t); + unicode_password = malloc(unicode_len); if (unicode_password == NULL) return (SMBAUTH_FAILURE); @@ -161,7 +160,9 @@ smb_auth_ntlm_hash(const char *password, unsigned char *hash) length = smb_auth_qnd_unicode(unicode_password, password, length); rc = smb_auth_md4(hash, (unsigned char *)unicode_password, length); + (void) memset(unicode_password, 0, unicode_len); free(unicode_password); + return (rc); } @@ -187,91 +188,6 @@ smb_auth_ntlm_response(unsigned char *hash, } /* - * smb_auth_gen_data_blob - * - * Fill the NTLMv2 data blob structure with information as described in - * "Implementing CIFS, The Common Internet File System". (pg. 282) - */ -static void -smb_auth_gen_data_blob(smb_auth_data_blob_t *blob, char *ntdomain) -{ - struct timeval now; - - (void) memset(blob->ndb_signature, 1, 2); - (void) memset(&blob->ndb_signature[2], 0, 2); - (void) memset(blob->ndb_reserved, 0, sizeof (blob->ndb_reserved)); - - (void) gettimeofday(&now, 0); - blob->ndb_timestamp = unix_micro_to_nt_time(&now); - randomize((char *)blob->ndb_clnt_challenge, - SMBAUTH_V2_CLNT_CHALLENGE_SZ); - (void) memset(blob->ndb_unknown, 0, sizeof (blob->ndb_unknown)); - blob->ndb_names[0].nne_len = smb_auth_qnd_unicode( - blob->ndb_names[0].nne_name, ntdomain, strlen(ntdomain)); - blob->ndb_names[0].nne_type = SMBAUTH_NAME_TYPE_DOMAIN_NETBIOS; - blob->ndb_names[1].nne_len = 0; - blob->ndb_names[1].nne_type = SMBAUTH_NAME_TYPE_LIST_END; - *blob->ndb_names[1].nne_name = 0; - (void) memset(blob->ndb_unknown2, 0, sizeof (blob->ndb_unknown2)); -} - -/* - * smb_auth_memcpy - * - * It increments the pointer to the destination buffer for the easy of - * concatenation. - */ -static void -smb_auth_memcpy(unsigned char **dstbuf, - unsigned char *srcbuf, - int srcbuf_len) -{ - (void) memcpy(*dstbuf, srcbuf, srcbuf_len); - *dstbuf += srcbuf_len; -} - -/* - * smb_auth_blob_to_string - * - * Prepare the data blob string which will be used in NTLMv2 response - * generation. - * - * Assumption: Caller must allocate big enough buffer to prevent buffer - * overrun. - * - * Returns the len of the data blob string. - */ -static int -smb_auth_blob_to_string(smb_auth_data_blob_t *blob, unsigned char *data_blob) -{ - unsigned char *bufp = data_blob; - - smb_auth_memcpy(&bufp, blob->ndb_signature, - sizeof (blob->ndb_signature)); - smb_auth_memcpy(&bufp, blob->ndb_reserved, - sizeof (blob->ndb_reserved)); - smb_auth_memcpy(&bufp, (unsigned char *)&blob->ndb_timestamp, - sizeof (blob->ndb_timestamp)); - smb_auth_memcpy(&bufp, blob->ndb_clnt_challenge, - SMBAUTH_V2_CLNT_CHALLENGE_SZ); - smb_auth_memcpy(&bufp, blob->ndb_unknown, sizeof (blob->ndb_unknown)); - smb_auth_memcpy(&bufp, (unsigned char *)&blob->ndb_names[0].nne_type, - sizeof (blob->ndb_names[0].nne_type)); - smb_auth_memcpy(&bufp, (unsigned char *)&blob->ndb_names[0].nne_len, - sizeof (blob->ndb_names[0].nne_len)); - smb_auth_memcpy(&bufp, (unsigned char *)blob->ndb_names[0].nne_name, - blob->ndb_names[0].nne_len); - smb_auth_memcpy(&bufp, (unsigned char *)&blob->ndb_names[1].nne_type, - sizeof (blob->ndb_names[1].nne_type)); - smb_auth_memcpy(&bufp, (unsigned char *)&blob->ndb_names[1].nne_len, - sizeof (blob->ndb_names[1].nne_len)); - smb_auth_memcpy(&bufp, blob->ndb_unknown2, sizeof (blob->ndb_unknown2)); - - /*LINTED E_PTRDIFF_OVERFLOW*/ - return (bufp - data_blob); -} - -/* * smb_auth_ntlmv2_hash * * The NTLM v2 hash will be created from the given NTLM hash, username, @@ -360,102 +276,6 @@ smb_auth_v2_response( } /* - * smb_auth_set_info - * - * Fill the smb_auth_info instance with either NTLM or NTLMv2 related - * authentication information based on the LMCompatibilityLevel. - * - * If the LMCompatibilityLevel equals 2, the SMB Redirector will perform - * NTLM challenge/response authentication which requires the NTLM hash and - * NTLM response. - * - * If the LMCompatibilityLevel is 3 or above, the SMB Redirector will - * perfrom NTLMv2 challenge/response authenticatoin which requires the - * NTLM hash, NTLMv2 hash, NTLMv2 response and LMv2 response. - * - * Returns -1 on error. Otherwise, returns 0 upon success. - */ -int -smb_auth_set_info(char *username, - char *password, - unsigned char *ntlm_hash, - char *domain, - unsigned char *srv_challenge_key, - int srv_challenge_len, - int lmcomp_lvl, - smb_auth_info_t *auth) -{ - unsigned short blob_len; - unsigned char blob_buf[SMBAUTH_BLOB_MAXLEN]; - int rc; - char *uppercase_dom; - - auth->lmcompatibility_lvl = lmcomp_lvl; - if (lmcomp_lvl == 2) { - auth->ci_len = 0; - *auth->ci = 0; - if (!ntlm_hash) { - if (smb_auth_ntlm_hash(password, auth->hash) != - SMBAUTH_SUCCESS) - return (-1); - } else { - (void) memcpy(auth->hash, ntlm_hash, SMBAUTH_HASH_SZ); - } - - auth->cs_len = smb_auth_ntlm_response(auth->hash, - srv_challenge_key, srv_challenge_len, auth->cs); - } else { - if (!ntlm_hash) { - if (smb_auth_ntlm_hash(password, auth->hash) != - SMBAUTH_SUCCESS) - return (-1); - } else { - (void) memcpy(auth->hash, ntlm_hash, SMBAUTH_HASH_SZ); - } - - if (!domain) - return (-1); - - if ((uppercase_dom = strdup(domain)) == NULL) - return (-1); - - (void) smb_strupr(uppercase_dom); - - if (smb_auth_ntlmv2_hash(auth->hash, username, - uppercase_dom, auth->hash_v2) != SMBAUTH_SUCCESS) { - free(uppercase_dom); - return (-1); - } - - /* generate data blob */ - smb_auth_gen_data_blob(&auth->data_blob, uppercase_dom); - free(uppercase_dom); - blob_len = smb_auth_blob_to_string(&auth->data_blob, blob_buf); - - /* generate NTLMv2 response */ - rc = smb_auth_v2_response(auth->hash_v2, srv_challenge_key, - srv_challenge_len, blob_buf, blob_len, auth->cs); - - if (rc < 0) - return (-1); - - auth->cs_len = rc; - - /* generate LMv2 response */ - rc = smb_auth_v2_response(auth->hash_v2, srv_challenge_key, - srv_challenge_len, auth->data_blob.ndb_clnt_challenge, - SMBAUTH_V2_CLNT_CHALLENGE_SZ, auth->ci); - - if (rc < 0) - return (-1); - - auth->ci_len = rc; - } - - return (0); -} - -/* * smb_auth_gen_session_key * * Generate the NTLM user session key if LMCompatibilityLevel is 2 or @@ -485,20 +305,6 @@ smb_auth_gen_session_key(smb_auth_info_t *auth, unsigned char *session_key) return (rc); } -/* 100's of ns between 1/1/1970 and 1/1/1601 */ -#define NT_TIME_BIAS (134774LL * 24LL * 60LL * 60LL * 10000000LL) - -static uint64_t -unix_micro_to_nt_time(struct timeval *unix_time) -{ - uint64_t nt_time; - - nt_time = unix_time->tv_sec; - nt_time *= 10000000; /* seconds to 100ns */ - nt_time += unix_time->tv_usec * 10; - return (nt_time + NT_TIME_BIAS); -} - static boolean_t smb_lm_password_ok( unsigned char *challenge, @@ -754,3 +560,42 @@ smb_auth_validate_nt( return (ok); } + +/* + * smb_gen_random_passwd(buf, len) + * Generate a random password of length len-1, and store it in buf, + * null terminated. This is used as a machine account password, + * which we set when we join a domain. + * + * [MS-DISO] A machine password is an ASCII string of randomly chosen + * characters. Each character's ASCII code is between 32 and 122 inclusive. + * That's space through 'z'. + */ + +int +smb_gen_random_passwd(char *buf, size_t len) +{ + const uchar_t start = ' '; + const uchar_t modulus = 'z' - ' ' + 1; + uchar_t t; + int i; + + /* Last byte is the null. */ + len--; + + /* Temporarily put random data in the caller's buffer. */ + randomize(buf, len); + + /* Convert the random data to printable characters. */ + for (i = 0; i < len; i++) { + /* need unsigned math */ + t = (uchar_t)buf[i]; + t = (t % modulus) + start; + assert(' ' <= t && t <= 'z'); + buf[i] = (char)t; + } + + buf[len] = '\0'; + + return (0); +} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c index 6270ca1af2..b59c582ca7 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c @@ -739,6 +739,32 @@ smb_config_get_fg_flag() } /* + * smb_config_get_ads_enable + * + * Returns value of the "config/use_ads" parameter + * from the IDMAP SMF configuration repository. + * + */ +boolean_t +smb_config_get_ads_enable(void) +{ + smb_scfhandle_t *handle = NULL; + uint8_t vbool; + int rc = 0; + + handle = smb_smf_scf_init(IDMAP_FMRI_PREFIX); + if (handle == NULL) + return (B_FALSE); + + rc = smb_smf_create_service_pgroup(handle, IDMAP_PG_NAME); + if (rc == SMBD_SMF_OK) + rc = smb_smf_get_boolean_property(handle, "use_ads", &vbool); + smb_smf_scf_fini(handle); + + return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE); +} + +/* * smb_config_get_localsid * * Returns value of the "config/machine_sid" parameter diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_crypt.c b/usr/src/lib/smbsrv/libsmb/common/smb_crypt.c index c6a95b7b43..7a1fb84709 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_crypt.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_crypt.c @@ -22,10 +22,9 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/md4.h> #include <sys/types.h> #include <string.h> @@ -37,6 +36,29 @@ static void smb_initlmkey(unsigned char *keyin, unsigned char *keyout); /* + * randomize + * + * Randomize the contents of the specified buffer. + */ +void +randomize(char *data, unsigned len) +{ + char *p = data; + + if (pkcs11_get_random(data, len) == 0) + return; + + /* + * Implement a "fall back", because current callers + * don't expect an error from this. In practice, + * we never use this fall back. + */ + while (len--) { + *p++ = (random() >> 24); + } +} + +/* * smb_auth_md4 * * Compute an MD4 digest. @@ -122,13 +144,21 @@ smb_auth_DES(unsigned char *Result, int ResultLen, int K, D; int k, d; - /* Calculate proper number of iterations */ + /* + * Calculate proper number of iterations. + * Known call cases include: + * ResultLen=16, KeyLen=14, DataLen=8 + * ResultLen=24, KeyLen=21, DataLen=8 + * ResultLen=16, KeyLen=14, DataLen=16 + */ K = KeyLen / 7; D = DataLen / 8; - - if (ResultLen < (K * 8 * D)) { - return (SMBAUTH_FAILURE); - } + if ((KeyLen % 7) || (DataLen % 8)) + return (EINVAL); + if (K == 0 || D == 0) + return (EINVAL); + if (ResultLen < (K * 8)) + return (EINVAL); /* * Use SUNW convenience function to initialize the cryptoki @@ -143,7 +173,10 @@ smb_auth_DES(unsigned char *Result, int ResultLen, return (SMBAUTH_FAILURE); } - for (k = 0; k < K; k++) { + for (d = k = 0; k < K; k++, d++) { + /* Cycle the input again, as necessary. */ + if (d == D) + d = 0; smb_initlmkey(&Key[k * 7], des_key); rv = SUNW_C_KeyToObject(hSession, mechanism.mechanism, des_key, 8, &hKey); @@ -157,18 +190,18 @@ smb_auth_DES(unsigned char *Result, int ResultLen, error = 1; goto exit_encrypt; } - ciphertext_len = DataLen; - for (d = 0; d < D; d++) { - /* Read in the data and encrypt this portion */ - rv = C_EncryptUpdate(hSession, - (CK_BYTE_PTR)Data + (d * 8), 8, - &Result[(k * (8 * D)) + (d * 8)], - &ciphertext_len); - if (rv != CKR_OK) { - error = 1; - goto exit_encrypt; - } + ciphertext_len = 8; + + /* Read in the data and encrypt this portion */ + rv = C_EncryptUpdate(hSession, + (CK_BYTE_PTR)Data + (d * 8), 8, + (CK_BYTE_PTR)Result + (k * 8), + &ciphertext_len); + if (rv != CKR_OK) { + error = 1; + goto exit_encrypt; } + (void) C_DestroyObject(hSession, hKey); } goto exit_session; @@ -204,3 +237,56 @@ smb_initlmkey(unsigned char *keyin, unsigned char *keyout) for (i = 0; i < 8; i++) keyout[i] = (keyout[i] << 1) & 0xfe; } + +/* + * CKM_RC4 + */ +int +smb_auth_RC4(uchar_t *Result, int ResultLen, + uchar_t *Key, int KeyLen, + uchar_t *Data, int DataLen) +{ + CK_RV rv; + CK_MECHANISM mechanism; + CK_OBJECT_HANDLE hKey; + CK_SESSION_HANDLE hSession; + CK_ULONG ciphertext_len; + int error = SMBAUTH_FAILURE; + + /* + * Use SUNW convenience function to initialize the cryptoki + * library, and open a session with a slot that supports + * the mechanism we plan on using. + */ + mechanism.mechanism = CKM_RC4; + mechanism.pParameter = NULL; + mechanism.ulParameterLen = 0; + rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession); + if (rv != CKR_OK) { + return (SMBAUTH_FAILURE); + } + + rv = SUNW_C_KeyToObject(hSession, mechanism.mechanism, + Key, KeyLen, &hKey); + if (rv != CKR_OK) + goto exit_session; + + /* Initialize the encryption operation in the session */ + rv = C_EncryptInit(hSession, &mechanism, hKey); + if (rv != CKR_OK) + goto exit_encrypt; + + ciphertext_len = ResultLen; + rv = C_EncryptUpdate(hSession, + (CK_BYTE_PTR)Data, DataLen, + (CK_BYTE_PTR)Result, &ciphertext_len); + if (rv == CKR_OK) + error = 0; + +exit_encrypt: + (void) C_DestroyObject(hSession, hKey); +exit_session: + (void) C_CloseSession(hSession); + + return (error); +} diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_util.c b/usr/src/lib/smbsrv/libsmb/common/smb_util.c index 3bd80e4425..91bf0a7b00 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_util.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_util.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #include <ctype.h> @@ -328,29 +328,6 @@ trim_whitespace(char *buf) } /* - * randomize - * - * Randomize the contents of the specified buffer. - */ -void -randomize(char *data, unsigned len) -{ - unsigned dwlen = len / 4; - unsigned remlen = len % 4; - unsigned tmp; - unsigned i; /*LINTED E_BAD_PTR_CAST_ALIGN*/ - unsigned *p = (unsigned *)data; - - for (i = 0; i < dwlen; ++i) - *p++ = random(); - - if (remlen) { - tmp = random(); - (void) memcpy(p, &tmp, remlen); - } -} - -/* * This is the hash mechanism used to encrypt passwords for commands like * SamrSetUserInformation. It uses a 256 byte s-box. */ diff --git a/usr/src/lib/smbsrv/libsmbns/Makefile.com b/usr/src/lib/smbsrv/libsmbns/Makefile.com index 840d6392c6..d148e11d65 100644 --- a/usr/src/lib/smbsrv/libsmbns/Makefile.com +++ b/usr/src/lib/smbsrv/libsmbns/Makefile.com @@ -48,8 +48,7 @@ SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \ $(OBJS_SHARED:%.o=$(SRC)/common/smbsrv/%.c) LDLIBS += $(MACH_LDLIBS) -LDLIBS += -lsmb -lgss -lcmdutils -lldap -lresolv -lnsl -lsocket -LDLIBS += -lc -lcryptoutil +LDLIBS += -lsmb -lgss -lcmdutils -lldap -lresolv -lnsl -lsocket -lc CPPFLAGS += -D_REENTRANT CERRWARN += -_gcc=-Wno-unused-function CERRWARN += -_gcc=-Wno-uninitialized diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h index ba54279da4..95d16b104e 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h +++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBSMBNS_H @@ -89,7 +90,7 @@ extern int smb_ads_lookup_share(smb_ads_handle_t *, const char *, const char *, char *); extern int smb_ads_add_share(smb_ads_handle_t *, const char *, const char *, const char *); -extern smb_adjoin_status_t smb_ads_join(char *, char *, char *, char *, size_t); +extern smb_adjoin_status_t smb_ads_join(char *, char *, char *, char *); extern void smb_ads_join_errmsg(smb_adjoin_status_t); extern boolean_t smb_ads_lookup_msdcs(char *, char *, char *, uint32_t); extern smb_ads_host_info_t *smb_ads_find_host(char *, char *); diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c index 5626d270ab..bcdfb8dbbf 100644 --- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c +++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #include <sys/param.h> @@ -62,13 +63,6 @@ #define SMB_ADS_SHARE_NUM_ATTR 3 #define SMB_ADS_SITE_MAX MAXHOSTNAMELEN -/* - * [MS-DISO] A machine password is an ASCII string of randomly chosen - * characters. Each character's ASCII code is between 32 and 122 inclusive. - */ -#define SMB_ADS_PWD_CHAR_NUM 91 -#define SMB_ADS_PWD_CHAR_START 32 - #define SMB_ADS_MSDCS_SRV_DC_RR "_ldap._tcp.dc._msdcs" #define SMB_ADS_MSDCS_SRV_SITE_RR "_ldap._tcp.%s._sites.dc._msdcs" @@ -209,7 +203,6 @@ static smb_ads_qstat_t smb_ads_lookup_computer_n_attr(smb_ads_handle_t *, smb_ads_avpair_t *, int, char *); static int smb_ads_update_computer_cntrl_attr(smb_ads_handle_t *, int, char *); static krb5_kvno smb_ads_lookup_computer_attr_kvno(smb_ads_handle_t *, char *); -static int smb_ads_gen_machine_passwd(char *, size_t); static void smb_ads_free_cached_host(void); static int smb_ads_alloc_attr(LDAPMod **, int); static void smb_ads_free_attr(LDAPMod **); @@ -2145,39 +2138,6 @@ smb_ads_lookup_computer_attr_kvno(smb_ads_handle_t *ah, char *dn) return (kvno); } -static int -smb_ads_gen_machine_passwd(char *machine_passwd, size_t bufsz) -{ - int i; - size_t pwdlen; - uint8_t *random_bytes; - - errno = 0; - if (machine_passwd == NULL || bufsz == 0) { - errno = EINVAL; - return (-1); - } - - pwdlen = bufsz - 1; - random_bytes = calloc(1, pwdlen); - if (random_bytes == NULL) - return (-1); - - if (pkcs11_get_random(random_bytes, pwdlen) != 0) { - free(random_bytes); - return (-1); - } - - for (i = 0; i < pwdlen; i++) - machine_passwd[i] = (random_bytes[i] % SMB_ADS_PWD_CHAR_NUM) + - SMB_ADS_PWD_CHAR_START; - - machine_passwd[pwdlen] = 0; - bzero(random_bytes, pwdlen); - free(random_bytes); - return (0); -} - /* * smb_ads_join * @@ -2204,8 +2164,7 @@ smb_ads_gen_machine_passwd(char *machine_passwd, size_t bufsz) * principal after the domain join operation. */ smb_adjoin_status_t -smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd, - size_t len) +smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd) { smb_ads_handle_t *ah = NULL; krb5_context ctx = NULL; @@ -2228,13 +2187,6 @@ smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd, return (SMB_ADJOIN_ERR_GET_HANDLE); } - if (smb_ads_gen_machine_passwd(machine_passwd, len) != 0) { - syslog(LOG_NOTICE, "machine password generation: %m"); - smb_ads_close(ah); - smb_ccache_remove(SMB_CCACHE_PATH); - return (SMB_ADJOIN_ERR_GEN_PWD); - } - if ((dclevel = smb_ads_get_dc_level(ah)) == -1) { smb_ads_close(ah); smb_ccache_remove(SMB_CCACHE_PATH); @@ -2294,6 +2246,7 @@ smb_ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd, cnt = spns.s_cnt; smb_krb5_free_pn_set(&spns); + /* New machine_passwd was filled in by our caller. */ if (smb_krb5_setpwd(ctx, ah->domain, machine_passwd) != 0) { rc = SMB_ADJOIN_ERR_KSETPWD; goto adjoin_cleanup; @@ -2360,16 +2313,6 @@ adjoin_cleanup: if (rename(tmpfile, SMBNS_KRB5_KEYTAB) != 0) { (void) unlink(tmpfile); rc = SMB_ADJOIN_ERR_COMMIT_KEYTAB; - } else { - /* Set IDMAP config */ - if (smb_config_set_idmap_domain(ah->domain) != 0) { - rc = SMB_ADJOIN_ERR_IDMAP_SET_DOMAIN; - } else { - - /* Refresh IDMAP service */ - if (smb_config_refresh_idmap() != 0) - rc = SMB_ADJOIN_ERR_IDMAP_REFRESH; - } } } else { (void) unlink(tmpfile); diff --git a/usr/src/man/man3head/in.h.3head b/usr/src/man/man3head/in.h.3head index 0e1a80010e..add74591c5 100644 --- a/usr/src/man/man3head/in.h.3head +++ b/usr/src/man/man3head/in.h.3head @@ -17,7 +17,6 @@ in.h, in \- Internet Protocol family .fi .SH DESCRIPTION -.sp .LP The <\fBnetinet/in.h\fR> header defines the following types through \fBtypedef\fR: @@ -121,7 +120,6 @@ The <\fBnetinet/in.h\fR> header defines the \fBsockaddr_in\fR structure that is used to store addresses for the Internet protocol family. Values of this type must be cast to \fBstruct sockaddr\fR for use with the socket interfaces. .SS "Default" -.sp .LP For applications that do not require standard-conforming behavior (those that use the socket interfaces described in section (3SOCKET) of the reference @@ -139,7 +137,6 @@ char sin_zero[8] .in -2 .SS "Standard conforming" -.sp .LP For applications that require standard-conforming behavior (those that use the socket interfaces described in section (3XNET) of the reference manual; see @@ -156,7 +153,6 @@ unsigned char sin_zero[8] .in -2 .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -172,10 +168,9 @@ Interface Stability Standard .TE .SH SEE ALSO -.sp .LP \fBIntro\fR(3), \fBconnect\fR(3SOCKET), \fBconnect\fR(3XNET), \fBgetsockopt\fR(3SOCKET), \fBgetsockopt\fR(3XNET), \fBsendmsg\fR(3SOCKET), \fBsendmsg\fR(3XNET), \fBsendto\fR(3SOCKET), \fBsendto\fR(3XNET), -\fBsetsockopt\fR(3SOCKET), \fBsetsockopt\fR(3XNET), \fBsocket.h\fR(3HEAD), -\fBattributes\fR(5), \fBstandards\fR(5) +\fBsetsockopt\fR(3SOCKET), \fBsetsockopt\fR(3XNET), \fBsockaddr\fR(3SOCKET), +\fBsocket.h\fR(3HEAD), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3head/socket.h.3head b/usr/src/man/man3head/socket.h.3head index ecd516e1b2..781dcf14f1 100644 --- a/usr/src/man/man3head/socket.h.3head +++ b/usr/src/man/man3head/socket.h.3head @@ -19,7 +19,6 @@ socket.h, socket \- Internet Protocol family .fi .SH DESCRIPTION -.sp .LP The \fB<sys/socket.h>\fR header defines the unsigned integral type \fBsa_family_t\fR through \fBtypedef\fR. @@ -37,7 +36,6 @@ char sa_data[] /* socket address (variable-length .in -2 .SS "\fBlibxnet\fR Interfaces" -.sp .LP The \fB<sys/socket.h>\fR header defines the \fBmsghdr\fR structure for \fBlibxnet\fR interfaces that includes the following members: @@ -689,7 +687,6 @@ Disables further send and receive operations. .RE .SS "\fBlibsocket\fR Interfaces" -.sp .LP The \fB<sys/socket.h>\fR header defines the \fBmsghdr\fR structure for \fBlibsocket\fR interfaces that includes the following members: @@ -714,7 +711,6 @@ in \fBread\fR(2). The \fImsg_accrights\fR parameter specifies the buffer in which access rights sent along with the message are received. The \fImsg_accrightslen\fR specifies the length of the buffer. .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -730,7 +726,6 @@ Interface Stability Standard .TE .SH SEE ALSO -.sp .LP \fBaccept\fR(3SOCKET), \fBaccept\fR(3XNET), \fBbind\fR(3SOCKET), \fBbind\fR(3XNET), \fBconnect\fR(3SOCKET), \fBconnect\fR(3XNET), @@ -743,6 +738,7 @@ Interface Stability Standard \fBsend\fR(3XNET), \fBsendmsg\fR(3SOCKET), \fBsendmsg\fR(3XNET), \fBsendto\fR(3SOCKET), \fBsendto\fR(3XNET), \fBsetsockopt\fR(3SOCKET), \fBsetsockopt\fR(3XNET), \fBshutdown\fR(3SOCKET), \fBshutdown\fR(3XNET), +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket\fR(3XNET), \fBsocketpair\fR(3SOCKET), \fBsocketpair\fR(3XNET), \fBucred_get\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3head/un.h.3head b/usr/src/man/man3head/un.h.3head index 155a845b6a..6af9dd8dda 100644 --- a/usr/src/man/man3head/un.h.3head +++ b/usr/src/man/man3head/un.h.3head @@ -17,7 +17,6 @@ un.h, un \- definitions for UNIX-domain sockets .fi .SH DESCRIPTION -.sp .LP The <\fBsys/un.h\fR> header defines the \fBsockaddr_un\fR structure that includes the following members: @@ -39,7 +38,6 @@ the socket interfaces. The <\fBsys/un.h\fR> header defines the type \fBsa_family_t\fR as described in \fBsocket.h\fR(3HEAD). .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -55,8 +53,8 @@ Interface Stability Standard .TE .SH SEE ALSO -.sp .LP \fBbind\fR(3SOCKET), \fBbind\fR(3XNET), \fBsocket.h\fR(3HEAD), \fBsocket\fR(3SOCKET), \fBsocket\fR(3XNET), \fBsocketpair\fR(3SOCKET), -\fBsocketpair\fR(3XNET), \fBattributes\fR(5), \fBstandards\fR(5) +\fBsocketpair\fR(3XNET), \fBsockaddr\fR(3SOCKET), \fBattributes\fR(5), +\fBstandards\fR(5) diff --git a/usr/src/man/man3sip/sip_stack_init.3sip b/usr/src/man/man3sip/sip_stack_init.3sip index 36e673fa7b..b2daf54386 100644 --- a/usr/src/man/man3sip/sip_stack_init.3sip +++ b/usr/src/man/man3sip/sip_stack_init.3sip @@ -16,7 +16,6 @@ sip_stack_init \- initializes SIP stack .fi .SH DESCRIPTION -.sp .LP The \fBsip_stack_init()\fR function is used to initialize the \fBSIP\fR stack. The stack can be initialized by a process only once. Any shared library that is @@ -60,7 +59,6 @@ all. .RE .SS "Upper Layer Registrations" -.sp .LP These include callbacks that are invoked to deliver incoming messages or error notification. @@ -177,7 +175,6 @@ If these callback routines are registered, the stack invokes .RE .SS "Connection Manager Interface" -.sp .LP The connection manager interfaces must be registered by the application to provide I/O related functionality to the stack. These interfaces act on a @@ -324,7 +321,6 @@ retransmit interval - default \fB32\fR \fBsecs\fR). .RE .SS "Custom \fBSIP\fR headers" -.sp .LP In addition to the \fBSIP\fR headers supported by the stack, an application can optionally provide a table of custom headers and associated parsing functions. @@ -414,7 +410,6 @@ application. .RE .SH RETURN VALUES -.sp .LP On success \fBsip_stack_init()\fR returns \fB0\fR. Otherwise, the function returns the error value. @@ -423,7 +418,6 @@ returns the error value. The value of \fBerrno\fR is not changed by these calls in the event of an error. .SH ERRORS -.sp .LP On failure, the \fBsip_stack_init()\fR function returns the following error value: @@ -438,7 +432,6 @@ missing. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -456,6 +449,5 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP -\fBlibsip\fR(3LIB) +\fBlibsip\fR(3LIB), \fBsockaddr\fR(3SOCKET) diff --git a/usr/src/man/man3socket/Makefile b/usr/src/man/man3socket/Makefile index a119ee08dc..c4bbd116c7 100644 --- a/usr/src/man/man3socket/Makefile +++ b/usr/src/man/man3socket/Makefile @@ -52,6 +52,7 @@ MANFILES= accept.3socket \ sctp_send.3socket \ sctp_sendmsg.3socket \ send.3socket \ + sockaddr.3socket \ shutdown.3socket \ socket.3socket \ socketpair.3socket \ @@ -136,7 +137,13 @@ MANLINKS= accept4.3socket \ setprotoent.3socket \ setservent.3socket \ setsockopt.3socket \ - setsourcefilter.3socket + setsourcefilter.3socket \ + sockaddr_dl.3socket \ + sockaddr_in.3socket \ + sockaddr_in6.3socket \ + sockaddr_ll.3socket \ + sockaddr_storage.3socket \ + sockaddr_un.3socket accept4.3socket := LINKSRC = accept.3socket @@ -239,6 +246,13 @@ sctp_freepaddrs.3socket := LINKSRC = sctp_getpaddrs.3socket sendmsg.3socket := LINKSRC = send.3socket sendto.3socket := LINKSRC = send.3socket +sockaddr_dl.3socket := LINKSRC = sockaddr.3socket +sockaddr_in.3socket := LINKSRC = sockaddr.3socket +sockaddr_in6.3socket := LINKSRC = sockaddr.3socket +sockaddr_ll.3socket := LINKSRC = sockaddr.3socket +sockaddr_storage.3socket := LINKSRC = sockaddr.3socket +sockaddr_un.3socket := LINKSRC = sockaddr.3socket + .KEEP_STATE: include $(SRC)/man/Makefile.man diff --git a/usr/src/man/man3socket/accept.3socket b/usr/src/man/man3socket/accept.3socket index c6afea7625..c253ba3aea 100644 --- a/usr/src/man/man3socket/accept.3socket +++ b/usr/src/man/man3socket/accept.3socket @@ -22,7 +22,6 @@ accept \- accept a connection on a socket .fi .SH DESCRIPTION -.sp .LP The argument \fIs\fR is a socket that has been created with \fBsocket\fR(3SOCKET) and bound to an address with \fBbind\fR(3SOCKET), and @@ -103,12 +102,10 @@ an \fBaccept()\fR by selecting or polling it for a read. However, this will only indicate when a connect indication is pending; it is still necessary to call \fBaccept()\fR. .SH RETURN VALUES -.sp .LP The \fBaccept()\fR function returns \fB\(mi1\fR on error. If it succeeds, it returns a non-negative integer that is a descriptor for the accepted socket. .SH ERRORS -.sp .LP \fBaccept()\fR and \fBaccept4()\fR will fail if: .sp @@ -239,7 +236,6 @@ bitwise inclusive-OR of \fBSOCK_CLOEXEC\fR, \fBSOCK_NONBLOCK\fR, and .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -255,9 +251,8 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBpoll\fR(2), \fBbind\fR(3SOCKET), \fBconnect\fR(3SOCKET), -\fBlisten\fR(3SOCKET), \fBselect\fR(3C), \fBsocket.h\fR(3HEAD), -\fBsocket\fR(3SOCKET), \fBnetconfig\fR(4), \fBattributes\fR(5), -\fBfcntl.h(3HEAD)\fR, \fBfcntl(2)\fR, \fBstandards(5)\fR +\fBlisten\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBselect\fR(3C), +\fBsocket.h\fR(3HEAD), \fBsocket\fR(3SOCKET), \fBnetconfig\fR(4), +\fBattributes\fR(5), \fBfcntl.h(3HEAD)\fR, \fBfcntl(2)\fR, \fBstandards(5)\fR diff --git a/usr/src/man/man3socket/bind.3socket b/usr/src/man/man3socket/bind.3socket index 723926dec4..8c0f1cdfd7 100644 --- a/usr/src/man/man3socket/bind.3socket +++ b/usr/src/man/man3socket/bind.3socket @@ -20,19 +20,16 @@ bind \- bind a name to a socket .fi .SH DESCRIPTION -.sp .LP The \fBbind()\fR function assigns a name to an unnamed socket. When a socket is created with \fBsocket\fR(3SOCKET), it exists in a name space (address family) but has no name assigned. The \fBbind()\fR function requests that the name pointed to by \fIname\fR be assigned to the socket. .SH RETURN VALUES -.sp .LP Upon successful completion \fB0\fR is returned. Otherwise, \fB\(mi1\fR is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBbind()\fR function will fail if: .sp @@ -174,7 +171,6 @@ The inode would reside on a read-only file system. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -190,12 +186,10 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP -\fBunlink\fR(2), \fBsocket\fR(3SOCKET), \fBattributes\fR(5), -\fBprivileges\fR(5), \fBsocket.h\fR(3HEAD) +\fBunlink\fR(2), \fBsocket\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBattributes\fR(5), \fBprivileges\fR(5), \fBsocket.h\fR(3HEAD) .SH NOTES -.sp .LP Binding a name in the UNIX domain creates a socket in the file system that must be deleted by the caller when it is no longer needed by using \fBunlink\fR(2). diff --git a/usr/src/man/man3socket/connect.3socket b/usr/src/man/man3socket/connect.3socket index d724a0d990..767eb2c79e 100644 --- a/usr/src/man/man3socket/connect.3socket +++ b/usr/src/man/man3socket/connect.3socket @@ -21,7 +21,6 @@ connect \- initiate a connection on a socket .fi .SH DESCRIPTION -.sp .LP The parameter \fIs\fR is a socket. If it is of type \fBSOCK_DGRAM\fR, \fBconnect()\fR specifies the peer with which the socket is to be associated. @@ -37,12 +36,10 @@ Generally, stream sockets can successfully \fBconnect()\fR only once. Datagram sockets can use \fBconnect()\fR multiple times to change their association. Datagram sockets can dissolve the association by connecting to a null address. .SH RETURN VALUES -.sp .LP If the connection or binding succeeds, \fB0\fR is returned. Otherwise, \fB\(mi1\fR is returned and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The call fails if: .sp @@ -288,7 +285,6 @@ type \fIs\fR. For example, \fIs\fR is a \fBSOCK_DGRAM\fR socket, while .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -304,8 +300,7 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBclose\fR(2), \fBaccept\fR(3SOCKET), \fBgetsockname\fR(3SOCKET), -\fBselect\fR(3C), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), -\fBattributes\fR(5) +\fBselect\fR(3C), \fBsocket\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBsocket.h\fR(3HEAD), \fBattributes\fR(5) diff --git a/usr/src/man/man3socket/getaddrinfo.3socket b/usr/src/man/man3socket/getaddrinfo.3socket index 135c8b5f80..1ab1f78d61 100644 --- a/usr/src/man/man3socket/getaddrinfo.3socket +++ b/usr/src/man/man3socket/getaddrinfo.3socket @@ -36,7 +36,6 @@ name and address .fi .SH DESCRIPTION -.sp .LP These functions perform translations from node name to address and from address to node name in a protocol-independent manner. @@ -295,7 +294,6 @@ TCP. These \fBNI_\fR* flags are defined in <\fBnetdb.h\fR> along with the \fBAI_\fR* flags already defined for \fBgetaddrinfo()\fR. .SH RETURN VALUES -.sp .LP For \fBgetaddrinfo()\fR, if the query is successful, a pointer to a linked list of one or more \fBaddrinfo\fR structures is returned by the fourth argument and @@ -310,7 +308,6 @@ pointer to a string containing an error message appropriate for the \fBEAI_\fR* errors is returned. If \fIerrcode\fR is not one of the \fBEAI_\fR* values, a pointer to a string indicating an unknown error is returned. .SS "Address Ordering" -.sp .LP AF_INET6 addresses returned by the fourth argument of \fBgetaddrinfo()\fR are ordered according to the algorithm described in \fIRFC 3484, Default Address @@ -371,7 +368,6 @@ T} .TE .SH ERRORS -.sp .LP The following names are the error values returned by \fBgetaddrinfo()\fR and are defined in <\fBnetdb.h\fR>: @@ -484,7 +480,6 @@ System error was returned in \fIerrno\fR. .RE .SH FILES -.sp .ne 2 .na \fB\fB/etc/inet/hosts\fR\fR @@ -512,7 +507,6 @@ configuration file for the name service switch .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for description of the following attributes: .sp @@ -532,17 +526,15 @@ Standard See \fBstandards\fR(5). .TE .SH SEE ALSO -.sp .LP \fBipaddrsel\fR(1M), \fBgethostbyname\fR(3NSL), \fBgetipnodebyname\fR(3SOCKET), -\fBhtonl\fR(3SOCKET), \fBinet\fR(3SOCKET), \fBnetdb.h\fR(3HEAD), -\fBsocket\fR(3SOCKET), \fBhosts\fR(4), \fBnsswitch.conf\fR(4), -\fBattributes\fR(5), \fBstandards\fR(5), \fBinet6\fR(7P) +\fBhtonl\fR(3SOCKET), \fBinet\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBnetdb.h\fR(3HEAD), \fBsocket\fR(3SOCKET), \fBhosts\fR(4), +\fBnsswitch.conf\fR(4), \fBattributes\fR(5), \fBstandards\fR(5), \fBinet6\fR(7P) .sp .LP Draves, R. \fIRFC 3484, Default Address Selection for Internet Protocol version 6 (IPv6)\fR. Network Working Group. February 2003. .SH NOTES -.sp .LP IPv4-mapped addresses are not recommended. diff --git a/usr/src/man/man3socket/getifaddrs.3socket b/usr/src/man/man3socket/getifaddrs.3socket index 2f303b2835..69324271af 100644 --- a/usr/src/man/man3socket/getifaddrs.3socket +++ b/usr/src/man/man3socket/getifaddrs.3socket @@ -36,7 +36,6 @@ getifaddrs, freeifaddrs \- get interface addresses .fi .SH DESCRIPTION -.sp .LP The \fBgetifaddrs\fR() function is used to obtain the list of network interfaces on the local machine. A reference to a linked list of \fBifaddrs\fR @@ -106,20 +105,17 @@ The memory used by \fBgetifaddrs\fR() to back the list is dynamically allocated. It should be freed using \fBfreeifaddrs\fR(). .SH RETURN VALUES -.sp .LP If successful, \fBgetifaddrs\fR() returns the value \fB0\fR; otherwise it returns \fB\(mi1\fR and sets \fIerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBgetifaddrs\fR() function may fail and set \fIerrno\fR for any of the errors specified for the library routines \fBioctl\fR(2), \fBsocket\fR(3SOCKET), and \fBmalloc\fR(3C). .SH ATTRIBUTES -.sp .TS box; c | c @@ -132,20 +128,17 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP \fBipadm\fR(1M), \fBifconfig\fR(1M), \fBioctl\fR(2), \fBmalloc\fR(3C), -\fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), \fBif_tcp\fR(7P), -\fBattributes\fR(5) +\fBsocket\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBsocket.h\fR(3HEAD), +\fBif_tcp\fR(7P), \fBattributes\fR(5) .SH NOTES -.sp .LP On an illumos system, this function lists only interfaces with the \fBIFF_UP\fR flag set; see \fBif_tcp\fR(7P) and \fBifconfig\fR(1M) for more information. .SH BUGS -.sp .LP At present, this function only lists addresses from the \fBAF_INET\fR and \fBAF_INET6\fR families. Other families, such as \fBAF_LINK\fR, are not diff --git a/usr/src/man/man3socket/getpeername.3socket b/usr/src/man/man3socket/getpeername.3socket index f8625adbdf..d1a6072637 100644 --- a/usr/src/man/man3socket/getpeername.3socket +++ b/usr/src/man/man3socket/getpeername.3socket @@ -17,7 +17,6 @@ getpeername \- get name of connected peer .fi .SH DESCRIPTION -.sp .LP \fBgetpeername()\fR returns the name of the peer connected to socket \fIs\fR. The \fBint\fR pointed to by the \fInamelen\fR parameter should be initialized @@ -25,12 +24,10 @@ to indicate the amount of space pointed to by \fIname\fR. On return it contains the actual size of the name returned (in bytes), prior to any truncation. The name is truncated if the buffer provided is too small. .SH RETURN VALUES -.sp .LP If successful, \fBgetpeername()\fR returns \fB0\fR; otherwise it returns \fB\(mi1\fR and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The call succeeds unless: .sp @@ -80,7 +77,6 @@ The argument \fIs\fR is not a socket. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -96,7 +92,7 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBaccept\fR(3SOCKET), \fBbind\fR(3SOCKET), \fBgetsockname\fR(3SOCKET), +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBattributes\fR(5), \fBsocket.h\fR(3HEAD) diff --git a/usr/src/man/man3socket/getsockname.3socket b/usr/src/man/man3socket/getsockname.3socket index a7ab0d1318..98e134bddd 100644 --- a/usr/src/man/man3socket/getsockname.3socket +++ b/usr/src/man/man3socket/getsockname.3socket @@ -17,19 +17,16 @@ getsockname \- get socket name .fi .SH DESCRIPTION -.sp .LP \fBgetsockname()\fR returns the current \fIname\fR for socket \fIs\fR. The \fInamelen\fR parameter should be initialized to indicate the amount of space pointed to by \fIname\fR. On return it contains the actual size in bytes of the name returned. .SH RETURN VALUES -.sp .LP If successful, \fBgetsockname()\fR returns \fB0\fR; otherwise it returns \fB\(mi1\fR and sets \fIerrno\fR to indicate the error. .SH ERRORS -.sp .LP The call succeeds unless: .sp @@ -70,7 +67,6 @@ The argument \fIs\fR is not a socket. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -86,7 +82,6 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP -\fBbind\fR(3SOCKET), \fBgetpeername\fR(3SOCKET), \fBsocket\fR(3SOCKET), -\fBattributes\fR(5) +\fBbind\fR(3SOCKET), \fBgetpeername\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBsocket\fR(3SOCKET), \fBattributes\fR(5) diff --git a/usr/src/man/man3socket/getsourcefilter.3socket b/usr/src/man/man3socket/getsourcefilter.3socket index 22d231a763..a5239ef898 100644 --- a/usr/src/man/man3socket/getsourcefilter.3socket +++ b/usr/src/man/man3socket/getsourcefilter.3socket @@ -40,7 +40,6 @@ retrieve and set a socket's multicast filter .fi .SH DESCRIPTION -.sp .LP These functions allow applications to retrieve and modify the multicast filtering state for a tuple consisting of socket, interface, and multicast @@ -109,12 +108,10 @@ number of addresses in the \fIslist\fR array. The \fIslist\fR argument points to the array of source addresses to be included or excluded, depending on the \fIfmode\fR value. .SH RETURN VALUES -.sp .LP If successful, all four functions return \fB0\fR. Otherwise, they return \fB\(mi1\fR and set \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP These functions will fail if: .sp @@ -202,7 +199,6 @@ The source filter list is larger than that allowed by the implementation. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -220,9 +216,9 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP -\fBif_nametoindex\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBattributes\fR(5) +\fBif_nametoindex\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBattributes\fR(5) .sp .LP RFC 3678 diff --git a/usr/src/man/man3socket/recv.3socket b/usr/src/man/man3socket/recv.3socket index fa011c4481..5f987e43f0 100644 --- a/usr/src/man/man3socket/recv.3socket +++ b/usr/src/man/man3socket/recv.3socket @@ -30,7 +30,6 @@ recv, recvfrom, recvmsg \- receive a message from a socket .fi .SH DESCRIPTION -.sp .LP The \fBrecv()\fR, \fBrecvfrom()\fR, and \fBrecvmsg()\fR functions are used to receive messages from another socket. The \fIs\fR socket is created with @@ -116,13 +115,11 @@ write requests are unaffected. The \fBrecvmsg()\fR function call uses a \fBmsghdr\fR structure defined in <\fBsys/socket.h\fR> to minimize the number of directly supplied parameters. .SH RETURN VALUES -.sp .LP Upon successful completion, these functions return the number of bytes received. Otherwise, they return \fB-1\fR and set \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBrecv()\fR, \fBrecvfrom()\fR, and \fBrecvmsg()\fR functions return errors under the following conditions: @@ -259,7 +256,6 @@ One of the \fIiov_len\fR values in the \fBmsg_iov\fR array member of the .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -277,9 +273,8 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBfcntl\fR(2), \fBioctl\fR(2), \fBread\fR(2), \fBconnect\fR(3SOCKET), \fBgetsockopt\fR(3SOCKET), \fBlibxnet\fR(3LIB), \fBselect\fR(3C), -\fBsend\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), -\fBattributes\fR(5) +\fBsend\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), +\fBsocket.h\fR(3HEAD), \fBattributes\fR(5) diff --git a/usr/src/man/man3socket/sctp_bindx.3socket b/usr/src/man/man3socket/sctp_bindx.3socket index 3f94ca2846..60f3fe905d 100644 --- a/usr/src/man/man3socket/sctp_bindx.3socket +++ b/usr/src/man/man3socket/sctp_bindx.3socket @@ -18,7 +18,6 @@ sctp_bindx \- add or remove IP addresses to or from an SCTP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_bindx()\fR function adds or removes addresses to or from an SCTP socket. If \fIsock\fR is an Internet Protocol Version 4 (IPv4) socket, @@ -68,13 +67,11 @@ addresses to or from an established association. In such a case, messages are exchanged between the SCTP endpoints to update the address lists for that association if both endpoints support dynamic address reconfiguration. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_bindx()\fR function returns \fB0\fR. Otherwise, the function returns \fB-1\fR and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBsctp_bindx()\fR call fails under the following conditions. .sp @@ -123,7 +120,6 @@ The last address is requested to be removed from an established association. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -141,14 +137,13 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBbind\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBlisten\fR(3SOCKET), \fBsctp_freeladdrs\fR(3SOCKET), \fBsctp_freepaddrs\fR(3SOCKET), \fBsctp_getladdrs\fR(3SOCKET), -\fBsctp_getpaddrs\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBinet\fR(7P), -\fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) +\fBsctp_getpaddrs\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), +\fBinet\fR(7P), \fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) + .SH NOTES -.sp .LP IPv4-mapped addresses are not recommended. diff --git a/usr/src/man/man3socket/sctp_getladdrs.3socket b/usr/src/man/man3socket/sctp_getladdrs.3socket index 255b0ca435..f343921788 100644 --- a/usr/src/man/man3socket/sctp_getladdrs.3socket +++ b/usr/src/man/man3socket/sctp_getladdrs.3socket @@ -24,7 +24,6 @@ SCTP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_getladdrs()\fR function queries addresses to which an SCTP socket is bound. The \fBsctp_freeladdrs()\fR function releases resources that are @@ -52,13 +51,11 @@ The \fBsctp_freeladdrs()\fR function frees the resources allocated by \fBsctp_getladdrs()\fR. The \fIaddrs\fR parameter is the array of addresses allocated by \fBsctp_getladdrs()\fR. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_getladdrs()\fR function returns the number of addresses in the \fIaddrs\fR array. Otherwise, the function returns \fB-1\fR and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBsctp_getladdrs()\fR call fails under the following conditions. .sp @@ -98,7 +95,6 @@ The \fIid\fR argument is an invalid socket. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -116,9 +112,9 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBbind\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBsctp_freepaddrs\fR(3SOCKET), \fBsctp_getpaddrs\fR(3SOCKET), +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBattributes\fR(5), \fBinet\fR(7P), \fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/sctp_getpaddrs.3socket b/usr/src/man/man3socket/sctp_getpaddrs.3socket index d816a3723c..c2558279b2 100644 --- a/usr/src/man/man3socket/sctp_getpaddrs.3socket +++ b/usr/src/man/man3socket/sctp_getpaddrs.3socket @@ -24,7 +24,6 @@ association .fi .SH DESCRIPTION -.sp .LP The \fBsctp_getpaddrs()\fR queries the peer addresses in an SCTP association. The \fBsctp_freepaddrs()\fR function releases resources that are allocated to @@ -51,13 +50,11 @@ The \fBsctp_freepaddrs()\fR function frees the resources allocated by \fBsctp_getpaddrs()\fR. The \fIaddrs\fR parameter is the array of addresses allocated by \fBsctp_getpaddrs()\fR. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_getpaddrs()\fR function returns the number of addresses in the \fIaddrs\fR array. Otherwise, the function returns \fB-1\fR and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBsctp_getpaddrs()\fR succeeds unless one of the following conditions exist. @@ -108,7 +105,6 @@ The specified socket is not connected. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -126,9 +122,9 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBbind\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBsctp_freeladdrs\fR(3SOCKET), \fBsctp_getladdrs\fR(3SOCKET), +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBattributes\fR(5), \fBinet\fR(7P), \fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/sctp_opt_info.3socket b/usr/src/man/man3socket/sctp_opt_info.3socket index 394b60d5a8..4323efb5f4 100644 --- a/usr/src/man/man3socket/sctp_opt_info.3socket +++ b/usr/src/man/man3socket/sctp_opt_info.3socket @@ -19,7 +19,6 @@ sctp_opt_info \- examine SCTP level options for an SCTP endpoint .fi .SH DESCRIPTION -.sp .LP The \fBsctp_opt_info()\fR returns SCTP level options associated with the SCTP socket \fIsock\fR. If \fIsock\fR is a one-to-many style socket, \fIid\fR refers @@ -274,13 +273,11 @@ where: .RE .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_opt_info()\fR function returns \fB0\fR. Otherwise, the function returns \fB-1\fR and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBsctp_opt_info()\fR call fails under the following conditions. .sp @@ -339,7 +336,6 @@ The address family for the peer's address is other than \fBAF_INET\fR or .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -357,8 +353,7 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBgetsockopt\fR(3SOCKET), -\fBsetsockopt\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBinet\fR(7P), -\fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) +\fBsetsockopt\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), +\fBinet\fR(7P), \fBinet6\fR(7P), \fBip\fR(7P), \fBip6\fR(7P), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/sctp_peeloff.3socket b/usr/src/man/man3socket/sctp_peeloff.3socket index 00449dfbbb..6dd770f3b1 100644 --- a/usr/src/man/man3socket/sctp_peeloff.3socket +++ b/usr/src/man/man3socket/sctp_peeloff.3socket @@ -20,7 +20,6 @@ to create a one-to-one STP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_peeloff()\fR function branches off an existing association from a one-to-many style SCTP socket into a separate socket file descriptor. The @@ -31,13 +30,11 @@ to operations allowed on a one-to-one style SCTP socket. The \fIsock\fR argument is a one-to-many socket. The association specified by the \fIid\fR argument is branched off \fIsock\fR. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_peeloff()\fR function returns the file descriptor that references the branched-off socket. The function returns \fB-1\fR if an error occurs. .SH ERRORS -.sp .LP The \fBsctp_peeloff()\fR function fails under the following conditions. .sp @@ -69,7 +66,6 @@ Failure to create a new user file descriptor or file structure. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -87,6 +83,5 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBsocket\fR(3SOCKET), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/sctp_recvmsg.3socket b/usr/src/man/man3socket/sctp_recvmsg.3socket index 8c5018b48e..875afc6714 100644 --- a/usr/src/man/man3socket/sctp_recvmsg.3socket +++ b/usr/src/man/man3socket/sctp_recvmsg.3socket @@ -20,7 +20,6 @@ sctp_recvmsg \- receive message from an SCTP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_recvmsg()\fR function receives a message from the SCTP endpoint \fIs\fR. @@ -71,12 +70,10 @@ The \fIsinfo\fR parameter is filled in only when the caller has enabled \fBsctp_data_io_events\fR by calling \fBsetsockopt()\fR with the socket option \fBSCTP_EVENTS\fR. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_recvmsg()\fR function returns the number of bytes received. The function returns \fB-1\fR if an error occurs. .SH ERRORS -.sp .LP The \fBsctp_recvmsg()\fR function fails under the following conditions. .sp @@ -116,7 +113,6 @@ There is no established association. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -134,10 +130,9 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBaccept\fR(3SOCKET), \fBbind\fR(3SOCKET), \fBconnect\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBlisten\fR(3SOCKET), -\fBrecvmsg\fR(3SOCKET), \fBsctp_opt_info\fR(3SOCKET), -\fBsetsockopt\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), +\fBrecvmsg\fR(3SOCKET), \fBsctp_opt_info\fR(3SOCKET), \fBsetsockopt\fR(3SOCKET), +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/sctp_send.3socket b/usr/src/man/man3socket/sctp_send.3socket index 81322ed3c1..3a44106596 100644 --- a/usr/src/man/man3socket/sctp_send.3socket +++ b/usr/src/man/man3socket/sctp_send.3socket @@ -19,7 +19,6 @@ sctp_send \- send message from an SCTP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_send()\fR function sends messages from one-to-one and one-to-many style SCTP endpoints. The following parameters can be set: @@ -61,12 +60,10 @@ parameter to send a message to the association represented in the ID. .LP Flags supported for \fBsctp_send()\fR are reserved for future use. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_send()\fR function returns the number of bytes sent. The function returns \fB-1\fR if an error occurs. .SH ERRORS -.sp .LP The \fBsctp_send()\fR function fails under the following conditions. .sp @@ -163,7 +160,6 @@ or \fBAF_INET6\fR. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -181,7 +177,6 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBaccept\fR(3SOCKET), \fBbind\fR(3SOCKET), \fBconnect\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBlisten\fR(3SOCKET), diff --git a/usr/src/man/man3socket/sctp_sendmsg.3socket b/usr/src/man/man3socket/sctp_sendmsg.3socket index 382e93b35f..281481a340 100644 --- a/usr/src/man/man3socket/sctp_sendmsg.3socket +++ b/usr/src/man/man3socket/sctp_sendmsg.3socket @@ -21,7 +21,6 @@ sctp_sendmsg \- send message from an SCTP socket .fi .SH DESCRIPTION -.sp .LP The \fBsctp_sendmsg()\fR function sends a message from the SCTP endpoint \fIs\fR. @@ -144,12 +143,10 @@ but it cannot be used subsequently on an existing association. Since \fBsctp_sendmsg()\fR always uses 0 internally as the association ID, it is not suitable for use on one-to-many sockets. .SH RETURN VALUES -.sp .LP Upon successful completion, the \fBsctp_sendmsg()\fR function returns the number of bytes sent. The function returns \fB-1\fR if an error occurs. .SH ERRORS -.sp .LP The \fBsctp_sendmsg()\fR function will fail if: .sp @@ -244,7 +241,6 @@ or \fBAF_INET6\fR. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -262,9 +258,8 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBaccept\fR(3SOCKET), \fBbind\fR(3SOCKET), \fBconnect\fR(3SOCKET), \fBin.h\fR(3HEAD), \fBlibsctp\fR(3LIB), \fBlisten\fR(3SOCKET), -\fBsendmsg\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), -\fBattributes\fR(5), \fBsctp\fR(7P) +\fBsendmsg\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), +\fBsocket.h\fR(3HEAD), \fBattributes\fR(5), \fBsctp\fR(7P) diff --git a/usr/src/man/man3socket/send.3socket b/usr/src/man/man3socket/send.3socket index 249b746b27..b37df998f7 100644 --- a/usr/src/man/man3socket/send.3socket +++ b/usr/src/man/man3socket/send.3socket @@ -29,7 +29,6 @@ send, sendto, sendmsg \- send a message from a socket .fi .SH DESCRIPTION -.sp .LP The \fBsend()\fR, \fBsendto()\fR, and \fBsendmsg()\fR functions are used to transmit a message to another transport end-point. The \fBsend()\fR function @@ -86,12 +85,10 @@ It is used only by diagnostic or routing programs. .LP See \fBrecv\fR(3SOCKET) for a description of the \fBmsghdr\fR structure. .SH RETURN VALUES -.sp .LP Upon successful completion, these functions return the number of bytes sent. Otherwise, they return \fB-1\fR and set \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBsend()\fR, \fBsendto()\fR, and \fBsendmsg()\fR functions return errors under the following conditions: @@ -248,7 +245,6 @@ longer connected. In the latter case, if the socket is of type .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -266,8 +262,8 @@ MT-Level Safe .TE .SH SEE ALSO -.sp .LP \fBfcntl\fR(2), \fBpoll\fR(2), \fBwrite\fR(2), \fBconnect\fR(3SOCKET), \fBgetsockopt\fR(3SOCKET), \fBrecv\fR(3SOCKET), \fBselect\fR(3C), -\fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), \fBattributes\fR(5) +\fBsockaddr\fR(3SOCKET), \fBsocket\fR(3SOCKET), \fBsocket.h\fR(3HEAD), +\fBattributes\fR(5) diff --git a/usr/src/man/man3socket/sockaddr.3socket b/usr/src/man/man3socket/sockaddr.3socket new file mode 100644 index 0000000000..842100d88d --- /dev/null +++ b/usr/src/man/man3socket/sockaddr.3socket @@ -0,0 +1,562 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright (c) 2014, Joyent, Inc. +.\" +.Dd Nov 13, 2014 +.Dt SOCKADDR 3SOCKET +.Os +.Sh NAME +.Nm sockaddr , +.Nm sockaddr_dl , +.Nm sockaddr_in , +.Nm sockaddr_in6 , +.Nm sockaddr_ll , +.Nm sockaddr_storage , +.Nm sockaddr_un +.Nd Socket Address Structures +.Sh SYNOPSIS +.In sys/socket.h +.Lp +.Sy struct sockaddr +.Em sock ; +.Lp +.In sys/socket.h +.In net/if_dl.h +.Lp +.Sy struct sockaddr_dl +.Em dl_sock ; +.Lp +.In sys/socket.h +.In netinet/in.h +.Lp +.Sy struct sockaddr_in +.Em in_sock ; +.Lp +.In sys/socket.h +.In netinet/in6.h +.Lp +.Sy struct sockaddr_in6 +.Em in6_sock ; +.Lp +.In sys/socket.h +.Lp +.Sy struct sockaddr_ll +.Em ll_sock ; +.Lp +.In sys/socket.h +.Lp +.Sy struct sockaddr_storage +.Em storage_sock ; +.Lp +.In sys/un.h +.Lp +.Sy struct sockaddr_un +.Em un_sock ; +.Sh DESCRIPTION +The +.Nm +family of structures are designed to represent network addresses for +different networking protocols. The structure +.Sy struct sockaddr +is a generic structure that is used across calls to various socket +library routines +.Po +.Xr libsocket 3LIB +.Pc +such as +.Xr accept 3SOCKET +and +.Xr bind 3SOCKET . +Applications do not use the +.Sy struct sockaddr +directly, but instead cast the appropriate networking family specific +.Nm +structure to a +.Sy struct sockaddr * . +.Lp +Every structure in the +.Nm +family begins with a member of the same type, the +.Sy sa_family_t , +though the different structures all have different names for the member. +For example, the structure +.Sy struct sockaddr +has the following members defined: +.Bd -literal -offset indent +sa_family_t sa_family /* address family */ +char sa_data[] /* socket address (variable-length data) */ +.Ed +.Lp +The member +.Em sa_family +corresponds to the socket family that's actually in use. The following +table describes the mapping between the address family and the +corresponding socket structure that's used. Note that both the generic +.Sy struct sockaddr +and the +.Sy struct sockaddr_storage +are not included, because these are both generic structures. More on the +.Sy struct sockaddr_storage +can be found in the next section. +.Bl -column -offset indent ".Sy Socket Structure" ".Sy Address Family" +.It Sy Socket Structure Ta Sy Address Family +.It struct sockaddr_dl Ta AF_LINK +.It struct sockaddr_in Ta AF_INET +.It struct sockaddr_in6 Ta AF_INET6 +.It struct sockaddr_ll Ta AF_PACKET +.It struct sockaddr_un Ta AF_UNIX +.El +.Ss struct sockaddr_storage +The +.Sy sockaddr_storage +structure is a +.Nm +that is not associated with an address family. Instead, it is large +enough to hold the contents of any of the other +.Nm +structures. It can be used to embed sufficient storage for a +.Sy sockaddr +of any type within a larger structure. +.Lp +The structure only has a single member defined. While there are other +members that are used to pad out the size of the +.Sy struct sockaddr_storage , +they are not defined and must not be consumed. The only valid +member is: +.Bd -literal -offset indent +sa_family_t ss_family /* address family */ +.Ed +.Lp +For example, +.Sy struct sockaddr_storage +is useful when running a service that accepts traffic over both +.Sy IPv4 +and +.Sy IPv6 +where it is common to use a single socket for both address families. In that +case, rather than guessing whether a +.Sy struct sockaddr_in +or a +.Sy struct sockaddr_in6 +is more appropriate, one can simply use a +.Sy struct sockaddr_storage +and cast to the appropriate family-specific structure type based on the +value of the member +.Em ss_family . +.Ss struct sockaddr_in +The +.Sy sockaddr_in +is the socket type which is used for for the Internet Protocol version +four (IPv4). It has the following members defined: +.Bd -literal -offset indent +sa_family_t sin_family /* address family */ +in_port_t sin_port /* IP port */ +struct in_addr sin_addr /* IP address */ +.Ed +.Lp +The member +.Em sin_family +must always have the value +.Sy AF_INET +for +.Sy IPv4 . +The members +.Em sin_port +and +.Em sin_addr +describe the IP address and IP port to use. In the case of a call to +.Xr connect 3SOCKET +these represent the remote IP address and port to which the connection +is being made. In the case of +.Xr bind 3SOCKET +these represent the IP address and port on the local host to which the socket +is to be bound. In the case of +.Xr accept 3SOCKET +these represent the remote IP address and port of the machine whose +connection was accepted. +.Lp +The member +.Em sin_port +is always stored in +.Sy Network Byte Order . +On many systems, this differs from the native host byte order. +Applications should read from the member with the function +.Xr ntohs 3SOCKET +and write to the member with the function +.Xr htons 3SOCKET . +The member +.Em sin_addr +is the four byte IPv4 address. It is also stored in network byte order. +The common way to write out the address is to use the function +.Xr inet_pton 3SOCKET +which converts between a human readable IP address such as "10.1.2.3" +and the corresponding representation. +.Lp +Example 1 shows how to prepare an IPv4 socket and deal with +network byte-order. See +.Xr inet 7P +and +.Xr ip 7P +for more information on IPv4, socket options, etc. +.Ss struct sockaddr_in6 +The +.Sy sockaddr_in6 +structure is the +.Nm +for the Internet Protocol version six (IPv6). Unlike the +.Sy struct sockaddr_in , +the +.Sy struct sockaddr_in6 +has additional members beyond those shown here which are required to be +initialized to zero through a function such as +.Xr bzero 3C +or +.Xr memset 3C . +If the entire +.Sy struct sockaddr_in6 +is not zeroed before use, applications will experience undefined behavior. The +.Sy struct sockaddr_in6 +has the following public members: +.Bd -literal -offset indent +sa_family_t sin6_family /* address family */ +in_port_t sin6_port /* IPv6 port */ +struct in6_addr sin6_addr /* IPv6 address */ +uint32_t sin6_flowinfo; /* traffic class and flow info */ +uint32_t sin6_scope_id; /* interface scope */ +.Ed +.Lp +The member +.Em sin6_family +must always have the value +.Sy AF_INET6 . +The members +.Em sin6_port +and +.Em sin6_addr +are the IPv6 equivalents of the +.Sy struct sockaddr_in +.Em sin_port +and +.Em sin_addr . +Like their IPv4 counterparts, both of these members must be in network +byte order. The member +.Em sin6_port +describes the IPv6 port and should be manipulated with the functions +.Xr ntohs 3SOCKET +and +.Xr htons 3SOCKET . +The member +.Em sin6_addr +describes the 16-byte IPv6 address. In addition to the function +.Xr inet_pton 3SOCKET , +the header file +.In netinet/in.h +defines many macros for manipulating and testing IPv6 addresses. +.Lp +The member +.Em sin6_flowinfo +contains the traffic class and flow label associated with the IPv6 +header. The member +.Em sin6_scope_id +may contain an identifier which varies based on the scope of the address +in +.Em sin6_addr . +Applications do not need to initialize +.Em sin6_scope_id ; +it will be populated by the operating system as a result of various library +calls. +.Lp +Example 2 shows how to prepare an IPv6 socket. For more information on +IPv6, please see +.Xr inet6 7P +and +.Xr ip6 7P . +.Ss struct sockaddr_un +The +.Sy sockaddr_un +structure specifies the address of a socket used to communicate between +processes running on a single system, commonly known as a +.Em UNIX domain socket . +Sockets of this type are identified by a path in the file system. The +.Sy struct sockaddr_un +has the following members: +.Bd -literal -offset indent +sa_family_t sun_family /* address family */ +char sun_path[108] /* path name */ +.Ed +.Lp +The member +.Em sun_family +must always have the value +.Sy AF_UNIX . +The member +.Em sun_path +is populated with a +.Sy NUL +terminated array of characters that specify a file system path. The maximum +length of any such path, including the +.Sy NUL +terminator, is 108 bytes. +.Ss struct sockaddr_dl +The +.Sy sockaddr_dl +structure is used to describe a layer 2 link-level address. This is used +as part of various socket ioctls, such as those for +.Xr arp 7P . +The structure has the following members: +.Bd -literal -offset indent +ushort_t sdl_family; /* address family */ +ushort_t sdl_index; /* if != 0, system interface index */ +uchar_t sdl_type; /* interface type */ +uchar_t sdl_nlen; /* interface name length */ +uchar_t sdl_alen; /* link level address length */ +uchar_t sdl_slen; /* link layer selector length */ +char sdl_data[244]; /* contains both if name and ll address +.Ed +.Lp +The member +.Em sdl_family +must always have the value +.Sy AF_LINK . +When the member +.Em sdl_index +is non-zero this refers to the interface identifier that corresponds to +the +.Sy struct sockaddr_dl . +This identifier is the same identifier that's shown by tools like +.Xr ifconfig 1M +and used in the SIOC* set of socket ioctls. The member +.Em sdl_type +refers to the media that is used for the socket. The most common case is +that the medium for the interface is Ethernet which has the value +.Sy IFT_ETHER . +The full set of types is derived from RFC1573 and recorded in the file +.In net/if_types.h . +The member +.Em sdl_slen +describes the length of a selector, if it exists, for the specified +medium. This is used in protocols such as Trill. +.Lp +The +.Em sdl_data , +.Em sdl_nlen +and +.Em sdl_alen +members together describe a character string containing the interface name and +the link-layer network address. The name starts at the beginning of +.Em sdl_data , +i.e. at +.Em sdl_data[0] . +The name of the interface occupies the next +.Em sdl_nlen +bytes and is not +.Sy NUL +terminated. The link-layer network address begins immediately after the +interface name, and is +.Em sdl_alen +bytes long. The macro +.Sy LLADDR(struct sockaddr_dl *) +returns the start of the link-layer network address. +The interpretation of the link-layer address depends on the value of +.Em sdl_type . +For example, if the type is +.Sy IFT_ETHER +then the address is expressed as a 6-byte MAC address. +.Ss struct sockaddr_ll +The +.Sy sockaddr_ll +is used as part of a socket type which is responsible for packet +capture: +.Sy AF_PACKET +sockets. It is generally designed for use with Ethernet networks. The members +of the +.Sy struct sockaddr_ll +are: +.Bd -literal -offset indent +uint16_t sll_family; /* address family */ +uint16_t sll_protocol; /* link layer protocol */ +int32_t sll_ifindex; /* interface index */ +uint16_t sll_hatype; /* ARP hardware type */ +uint8_t sll_pkttype; /* packet type */ +uint8_t sll_halen; /* hardware address length */ +uint8_t sll_addr[8]; /* hardware type */ +.Ed +.Lp +The member +.Em sll_family +must be +.Sy AF_PACKET . +The member +.Em sll_protocol +refers to a link-layer protocol. For example, when capturing Ethernet frames +the value of +.Em sll_protocol +is the Ethertype. This member is written in network byte order and +applications should use +.Xr htons 3SOCKET +and +.Xr ntohs 3SOCKET +to read and write the member. +.Lp +The member +.Em sll_ifindex +is the interface's index. It is used as an identifier in various ioctls +and included in the output of +.Xr ifconfig 1M . +When calling +.Xr bind 3SOCKET +it should be filled in with the index that corresponds to the interface +for which packets should be captured on. +.Lp +The member +.Em sll_pkttype +describes the type of the packet based on a list of types in the header +file +.In netpacket/packet.h . +These types include: +.Sy PACKET_OUTGOING , +a packet that was leaving the host and has been looped back for packet capture; +.Sy PACKET_HOST , +a packet that was destined for this host; +.Sy PACKET_BROADCAST , +a packet that was broadcast across the link-layer; +.Sy PACKET_MULTICAST , +a packet that was sent to a link-layer multicast address; and +.Sy PACKET_OTHERHOST , +a packet that was captured only because the device in question was in +promiscuous mode. +.Lp +The member +.Em sll_hatype +contains the hardware type as defined by +.Xr arp 7P . +The list of types can be found in +.In net/if_arp.h . +The member +.Em sll_halen +contains the length, in bytes, of the hardware address, while the member +.Em sll_addr +contains the actual address in network byte order. +.Sh EXAMPLES +.Sy Example 1 +Preparing an IPv4 +.Sy sockaddr_in +to connect to a remote host +.Lp +The following example shows how one would open a socket and prepare it +to connect to the remote host whose address is the IP address 127.0.0.1 +on port 80. This program should be compiled with the C compiler +.Sy cc +and linked against the libraries libsocket and libnsl. If this example +was named ip4.c, then the full link line would be +.Ic cc ip4.c -lsocket -lnsl . +.Bd -literal +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <netinet/in.h> +#include <inttypes.h> +#include <strings.h> + +int +main(void) +{ + int sock; + struct sockaddr_in in; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return (1); + } + + bzero(&in, sizeof (struct sockaddr_in)); + in.sin_family = AF_INET; + in.sin_port = htons(80); + if (inet_pton(AF_INET, "127.0.0.1", &in.sin_addr) != 1) { + perror("inet_pton"); + return (1); + } + + if (connect(sock, (struct sockaddr *)&in, + sizeof (struct sockaddr_in)) != 0) { + perror("connect"); + return (1); + } + + /* use socket */ + + return (0); +} +.Ed +.Lp +.Sy Example 2 +Preparing an IPv6 +.Sy sockaddr_in6 +to bind to a local address +.Lp +The following example shows how one would open a socket and prepare it +to bind to the local IPv6 address ::1 port on port 12345. This program +should be compiled with the C compiler +.Sy cc +and linked aginst the libraries libsocket and libnsl. If this example +was named ip6.c, then the full compiler line would be +.Ic cc ip6.c -lsocket -lnsl . +.Bd -literal +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <netinet/in.h> +#include <inttypes.h> +#include <strings.h> + +int +main(void) +{ + int sock6; + struct sockaddr_in6 in6; + + if ((sock6 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return (1); + } + + bzero(&in6, sizeof (struct sockaddr_in6)); + in6.sin6_family = AF_INET6; + in6.sin6_port = htons(12345); + if (inet_pton(AF_INET6, "::1", &in6.sin6_addr) != 1) { + perror("inet_pton"); + return (1); + } + + if (bind(sock6, (struct sockaddr *)&in6, + sizeof (struct sockaddr_in6)) != 0) { + perror("bind"); + return (1); + } + + /* use server socket */ + + return (0); +} +.Ed +.Sh SEE ALSO +.Xr socket 3HEAD , +.Xr uh.h 3HEAD , +.Xr accept 3SOCKET , +.Xr bind 3SOCKET , +.Xr connect 3SOCKET , +.Xr socket 3SOCKET , +.Xr arp 7P , +.Xr inet 7P , +.Xr inet6 7P , +.Xr ip 7P , +.Xr ip6 7P , diff --git a/usr/src/man/man3xnet/accept.3xnet b/usr/src/man/man3xnet/accept.3xnet index 79037af1f8..2b78155438 100644 --- a/usr/src/man/man3xnet/accept.3xnet +++ b/usr/src/man/man3xnet/accept.3xnet @@ -22,7 +22,6 @@ accept \- accept a new connection on a socket .fi .SH DESCRIPTION -.sp .LP The \fBaccept()\fR function extracts the first connection on the queue of pending connections, creates a new socket with the same socket type protocol @@ -91,18 +90,15 @@ requests and O_NONBLOCK is set on the file descriptor for the socket, The accepted socket cannot itself accept more connections. The original socket remains open and can accept more connections. .SH USAGE -.sp .LP When a connection is available, \fBselect\fR(3C) will indicate that the file descriptor for the socket is ready for reading. .SH RETURN VALUES -.sp .LP Upon successful completion, \fBaccept()\fR returns the nonnegative file descriptor of the accepted socket. Otherwise, \(mi1 is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBaccept()\fR function will fail if: .sp @@ -243,7 +239,6 @@ been initialized. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -261,7 +256,7 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBbind\fR(3XNET), \fBconnect\fR(3XNET), \fBlisten\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3xnet/bind.3xnet b/usr/src/man/man3xnet/bind.3xnet index 45772c3ff8..12be69fbe3 100644 --- a/usr/src/man/man3xnet/bind.3xnet +++ b/usr/src/man/man3xnet/bind.3xnet @@ -22,7 +22,6 @@ bind \- bind a name to a socket .fi .SH DESCRIPTION -.sp .LP The \fBbind()\fR function assigns an \fIaddress\fR to an unnamed socket. Sockets created with \fBsocket\fR(3XNET) function are initially unnamed. They @@ -65,17 +64,14 @@ Specifies the length of the \fBsockaddr\fR structure pointed to by the The socket in use may require the process to have appropriate privileges to use the \fBbind()\fR function. .SH USAGE -.sp .LP An application program can retrieve the assigned socket name with the \fBgetsockname\fR(3XNET) function. .SH RETURN VALUES -.sp .LP Upon successful completion, \fBbind()\fR returns 0. Otherwise, \(mi1 is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBbind()\fR function will fail if: .sp @@ -296,7 +292,6 @@ There were insufficient STREAMS resources for the operation to complete. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -314,8 +309,8 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBconnect\fR(3XNET), \fBgetsockname\fR(3XNET), \fBlisten\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), \fBprivileges\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3xnet/connect.3xnet b/usr/src/man/man3xnet/connect.3xnet index 50c08bb6c2..14e2ab5494 100644 --- a/usr/src/man/man3xnet/connect.3xnet +++ b/usr/src/man/man3xnet/connect.3xnet @@ -21,7 +21,6 @@ connect \- connect a socket .fi .SH DESCRIPTION -.sp .LP The \fBconnect()\fR function requests a connection to be made on a socket. The function takes the following arguments: @@ -100,18 +99,15 @@ for writing. The socket in use may require the process to have appropriate privileges to use the \fBconnect()\fR function. .SH USAGE -.sp .LP If \fBconnect()\fR fails, the state of the socket is unspecified. Portable applications should close the file descriptor and create a new socket before attempting to reconnect. .SH RETURN VALUES -.sp .LP Upon successful completion, \fBconnect()\fR returns 0. Otherwise, \(mi1 is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBconnect()\fR function will fail if: .sp @@ -388,7 +384,6 @@ The socket is listening and can not be connected. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -406,8 +401,8 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBclose\fR(2), \fBpoll\fR(2), \fBaccept\fR(3XNET), \fBbind\fR(3XNET), \fBgetsockname\fR(3XNET), \fBselect\fR(3C), \fBsend\fR(3XNET), \fBshutdown\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), diff --git a/usr/src/man/man3xnet/getnameinfo.3xnet b/usr/src/man/man3xnet/getnameinfo.3xnet index 60cef94c6c..b7f43685bd 100644 --- a/usr/src/man/man3xnet/getnameinfo.3xnet +++ b/usr/src/man/man3xnet/getnameinfo.3xnet @@ -24,7 +24,6 @@ getnameinfo \- get name information .fi .SH DESCRIPTION -.sp .LP The \fBgetnameinfo()\fR function translates a socket address to a node name and service location, all of which are defined as in \fBgetaddrinfo\fR(3XNET). @@ -94,7 +93,6 @@ datagram service (\fBSOCK_DGRAM\fR). The default behavior assumes that the service is a stream service (\fBSOCK_STREAM\fR). .RE .SH RETURN VALUES -.sp .LP A 0 return value for \fBgetnameinfo()\fR indicates successful completion; a non-zero return value indicates failure. The possible values for the failures @@ -105,7 +103,6 @@ Upon successful completion, \fBgetnameinfo()\fR returns the node and service names, if requested, in the buffers provided. The returned names are always null-terminated strings. .SH ERRORS -.sp .LP The \fBgetnameinfo()\fR function will fail if: .sp @@ -175,7 +172,6 @@ A system error occurred. The error code can be found in \fBerrno\fR. .RE .SH USAGE -.sp .LP If the returned values are to be used as part of any further name resolution (for example, passed to \fBgetaddrinfo()\fR), applications should provide @@ -186,7 +182,6 @@ Given the IPv4-mapped IPv6 address "::ffff:1.2.3.4", the implementation performs a lookup as if the socket address structure contains the IPv4 address "1.2.3.4". .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -204,13 +199,12 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBgai_strerror\fR(3XNET), \fBgetaddrinfo\fR(3XNET), \fBgetservbyname\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), \fBstandards\fR(5) .SH NOTES -.sp .LP The IPv6 unspecified address ("::") and the IPv6 loopback address ("::1") are not IPv4-compatible addresses. If the address is the IPv6 unspecified address diff --git a/usr/src/man/man3xnet/getpeername.3xnet b/usr/src/man/man3xnet/getpeername.3xnet index ed96bd2bf2..4ed8a0bb75 100644 --- a/usr/src/man/man3xnet/getpeername.3xnet +++ b/usr/src/man/man3xnet/getpeername.3xnet @@ -21,7 +21,6 @@ getpeername \- get the name of the peer socket .fi .SH DESCRIPTION -.sp .LP The \fBgetpeername()\fR function retrieves the peer address of the specified socket, stores this address in the \fBsockaddr\fR structure pointed to by the @@ -37,12 +36,10 @@ If the protocol permits connections by unbound clients, and the peer is not bound, then the value stored in the object pointed to by \fIaddress\fR is unspecified. .SH RETURN VALUES -.sp .LP Upon successful completion, 0 is returned. Otherwise, \(mi1 is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBgetpeername()\fR function will fail if: .sp @@ -123,7 +120,6 @@ complete. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -141,7 +137,7 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBaccept\fR(3XNET), \fBbind\fR(3XNET), \fBgetsockname\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3xnet/getsockname.3xnet b/usr/src/man/man3xnet/getsockname.3xnet index 9afeb8cb07..73d3e5206e 100644 --- a/usr/src/man/man3xnet/getsockname.3xnet +++ b/usr/src/man/man3xnet/getsockname.3xnet @@ -21,7 +21,6 @@ getsockname \- get the socket name .fi .SH DESCRIPTION -.sp .LP The \fBgetsockname()\fR function retrieves the locally-bound name of the specified socket, stores this address in the \fBsockaddr\fR structure pointed @@ -36,14 +35,12 @@ If the actual length of the address is greater than the length of the supplied If the socket has not been bound to a local name, the value stored in the object pointed to by \fIaddress\fR is unspecified. .SH RETURN VALUES -.sp .LP Upon successful completion, 0 is returned, the \fIaddress\fR argument points to the address of the socket, and the \fIaddress_len\fR argument points to the length of the address. Otherwise, \(mi1 is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBgetsockname()\fR function will fail: .sp @@ -115,7 +112,6 @@ complete. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -133,7 +129,7 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP +\fBsockaddr\fR(3SOCKET), \fBaccept\fR(3XNET), \fBbind\fR(3XNET), \fBgetpeername\fR(3XNET), \fBsocket\fR(3XNET) \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3xnet/recvfrom.3xnet b/usr/src/man/man3xnet/recvfrom.3xnet index 2d1eec2fcc..1e03959d4d 100644 --- a/usr/src/man/man3xnet/recvfrom.3xnet +++ b/usr/src/man/man3xnet/recvfrom.3xnet @@ -22,7 +22,6 @@ recvfrom \- receive a message from a socket .fi .SH DESCRIPTION -.sp .LP The \fBrecvfrom()\fR function receives a message from a connection-mode or connectionless-mode socket. It is normally used with connectionless-mode @@ -161,19 +160,16 @@ If no messages are available at the socket and \fBO_NONBLOCK\fR is set on the socket's file descriptor, \fBrecvfrom()\fR fails and sets \fBerrno\fR to \fBEAGAIN\fR or \fBEWOULDBLOCK\fR. .SH USAGE -.sp .LP The \fBselect\fR(3C) and \fBpoll\fR(2) functions can be used to determine when data is available to be received. .SH RETURN VALUES -.sp .LP Upon successful completion, \fBrecvfrom()\fR returns the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, \fBrecvfrom()\fR returns 0. Otherwise the function returns \(mi1 and sets \fBerrno\fR to indicate the error. .SH ERRORS -.sp .LP The \fBrecvfrom()\fR function will fail if: .sp @@ -316,7 +312,6 @@ complete. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -334,9 +329,9 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP -\fBpoll\fR(2), \fBrecv\fR(3XNET), \fBrecvmsg\fR(3XNET), \fBselect\fR(3C) +\fBpoll\fR(2), \fBsockaddr\fR(3SOCKET), +\fBrecv\fR(3XNET), \fBrecvmsg\fR(3XNET), \fBselect\fR(3C) \fBsend\fR(3XNET), \fBsendmsg\fR(3XNET), \fBsendto\fR(3XNET), \fBshutdown\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3xnet/sendto.3xnet b/usr/src/man/man3xnet/sendto.3xnet index 9c9e75bc57..a3e6bc81f5 100644 --- a/usr/src/man/man3xnet/sendto.3xnet +++ b/usr/src/man/man3xnet/sendto.3xnet @@ -21,7 +21,6 @@ sendto \- send a message on a socket .fi .SH DESCRIPTION -.sp .LP The \fBsendto()\fR function sends a message through a connection-mode or connectionless-mode socket. If the socket is connectionless-mode, the message @@ -53,7 +52,6 @@ descriptor does have \fBO_NONBLOCK\fR set, \fBsendto()\fR will fail. The socket in use may require the process to have appropriate privileges to use the \fBsendto()\fR function. .SH PARAMETERS -.sp .LP The function takes the following arguments: .sp @@ -133,17 +131,14 @@ Specifies the length of the \fBsockaddr\fR structure pointed to by the .RE .SH USAGE -.sp .LP The \fBselect\fR(3C) and \fBpoll\fR(2) functions can be used to determine when it is possible to send more data. .SH RETURN VALUES -.sp .LP Upon successful completion, \fBsendto()\fR returns the number of bytes sent. Otherwise, \fB-1\fR is returned and \fBerrno\fR is set to indicate the error. .SH ERRORS -.sp .LP The \fBsendto()\fR function will fail if: .sp @@ -427,7 +422,6 @@ length exceeds \fIPATH_MAX\fR. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -445,9 +439,9 @@ MT-Level MT-Safe .TE .SH SEE ALSO -.sp .LP -\fBpoll\fR(2), \fBgetsockopt\fR(3XNET), \fBrecv\fR(3XNET), +\fBpoll\fR(2), \fBsockaddr\fR(3SOCKET), +\fBgetsockopt\fR(3XNET), \fBrecv\fR(3XNET), \fBrecvfrom\fR(3XNET), \fBrecvmsg\fR(3XNET), \fBselect\fR(3C), \fBsend\fR(3XNET), \fBsendmsg\fR(3XNET), \fBsetsockopt\fR(3XNET), \fBshutdown\fR(3XNET), \fBsocket\fR(3XNET), \fBattributes\fR(5), diff --git a/usr/src/man/man7p/arp.7p b/usr/src/man/man7p/arp.7p index 70b86e0ac3..5489ce3aca 100644 --- a/usr/src/man/man7p/arp.7p +++ b/usr/src/man/man7p/arp.7p @@ -39,7 +39,6 @@ arp, ARP \- Address Resolution Protocol .fi .SH DESCRIPTION -.sp .LP ARP is a protocol used to map dynamically between Internet Protocol (IP) and Ethernet addresses. It is used by all Ethernet datalink providers (network @@ -57,7 +56,6 @@ caches the new mapping and transmits any pending message. \fBARP\fR will queue a maximum of four packets while awaiting a response to a mapping request. ARP keeps only the first four transmitted packets. .SH APPLICATION PROGRAMMING INTERFACE -.sp .LP The STREAMS device \fB/dev/arp\fR is not a Transport Level Interface (\fBTLI\fR) transport provider and may not be used with the \fBTLI\fR @@ -280,7 +278,6 @@ excess of conflicts. ARP also handles UNARP messages received from other nodes. It does not generate these messages. .SH PACKET EVENTS -.sp .LP The \fBarp\fR driver registers itself with the netinfo interface. To gain access to these events, a handle from net_protocol_lookup must be acquired by @@ -348,7 +345,6 @@ Pointer to the mblk_t with the ARP header in it. .RE .SH NETWORK INTERFACE EVENTS -.sp .LP In addition to events describing packets as they move through the system, it is also possible to receive notification of events relating to network @@ -375,10 +371,9 @@ A network interface is no longer associated with ARP. .RE .SH SEE ALSO -.sp .LP -\fBarp\fR(1M), \fBifconfig\fR(1M), \fBprivileges\fR(5), \fBif_tcp\fR(7P), -\fBinet\fR(7P), \fBnetinfo\fR(9F) +\fBarp\fR(1M), \fBifconfig\fR(1M), \fBsockaddr\fR(3SOCKET), \fBprivileges\fR(5), +\fBif_tcp\fR(7P), \fBinet\fR(7P), \fBnetinfo\fR(9F) .sp .LP Plummer, Dave, \fIAn Ethernet Address Resolution Protocol\fR or \fIConverting @@ -388,7 +383,6 @@ Ethernet Hardware\fR, RFC 826, STD 0037, November 1982. .LP Malkin, Gary, \fIARP Extension - UNARP, RFC 1868\fR, November, 1995 .SH DIAGNOSTICS -.sp .LP Several messages can be written to the system logs (by the IP module) when errors occur. In the following examples, the hardware address strings include diff --git a/usr/src/man/man7p/if_tcp.7p b/usr/src/man/man7p/if_tcp.7p index d59ecc90af..6f811bd12c 100644 --- a/usr/src/man/man7p/if_tcp.7p +++ b/usr/src/man/man7p/if_tcp.7p @@ -8,7 +8,6 @@ .SH NAME if_tcp, if \- general properties of Internet Protocol network interfaces .SH DESCRIPTION -.sp .LP A network interface is a device for sending and receiving packets on a network. It is usually a hardware device, although it can be implemented in software. @@ -16,7 +15,6 @@ Network interfaces used by the Internet Protocol (IPv4 or IPv6) must be STREAMS devices conforming to the Data Link Provider Interface (\fBDLPI\fR). See \fBdlpi\fR(7P). .SH APPLICATION PROGRAMMING INTERFACE -.sp .LP An interface becomes available to \fBIP\fR when it is opened and the \fBIP\fR module is pushed onto the stream with the \fBI_PUSH\fR \fBioctl\fR(2) command. @@ -37,7 +35,6 @@ when an interface's address is set. You cannot create IPMP IP interfaces using the procedure described above. Instead, use \fBifconfig\fR(1M). .SH IOCTLS -.sp .LP The following \fBioctl()\fR calls may be used to manipulate \fBIP\fR network interfaces. Unless specified otherwise, the request takes an \fBlifreq\fR @@ -749,7 +746,6 @@ struct ifconf { .in -2 .SS "IFF_ Flags" -.sp .LP You can use the \fBifconfig\fR(1M) command to display the \fBIFF\fR_ flags listed below (with the leading \fBIFF\fR_ prefix removed). See the @@ -809,7 +805,6 @@ listed below (with the leading \fBIFF\fR_ prefix removed). See the .in -2 .SH ERRORS -.sp .ne 2 .na \fB\fBEPERM\fR\fR @@ -871,7 +866,7 @@ specified by \fBlifr_ppa\fR plumbed. .RE .SH SEE ALSO -.sp .LP -\fBifconfig\fR(1M), \fBin.routed\fR(1M), \fBioctl\fR(2), \fBstreamio\fR(7I), -\fBarp\fR(7P), \fBdlpi\fR(7P), \fBip\fR(7P), \fBip6\fR(7P) +\fBifconfig\fR(1M), \fBin.routed\fR(1M), \fBioctl\fR(2), +\fBsockaddr\fR(3SOCKET), \fBstreamio\fR(7I), \fBarp\fR(7P), \fBdlpi\fR(7P), +\fBip\fR(7P), \fBip6\fR(7P) diff --git a/usr/src/man/man7p/inet.7p b/usr/src/man/man7p/inet.7p index b41d131de8..385fcdfa72 100644 --- a/usr/src/man/man7p/inet.7p +++ b/usr/src/man/man7p/inet.7p @@ -19,7 +19,6 @@ inet \- Internet protocol family .fi .SH DESCRIPTION -.sp .LP The Internet protocol family implements a collection of protocols which are centered around the Internet Protocol ("\fBIP\fR") and which share a common @@ -29,7 +28,6 @@ interface, where they support the \fBSOCK_STREAM\fR, \fBSOCK_DGRAM\fR, and support the connectionless (\fBT_CLTS\fR) and connection oriented (\fBT_COTS_ORD\fR) service types. .SH PROTOCOLS -.sp .LP The Internet protocol family is comprised of the Internet Protocol ("\fBIP\fR"), the Address Resolution Protocol ("\fBARP\fR"), the Internet @@ -83,7 +81,6 @@ Get interface network mask. .RE .SH ADDRESSING -.sp .LP \fBIP\fR addresses are four byte quantities, stored in network byte order. \fBIP\fR addresses should be manipulated using the byte order conversion @@ -155,19 +152,18 @@ restriction by setting the \fBSO_REUSEADDR\fR socket option with numbers. These semantics apply when Internet family protocols are used using the \fBTLI\fR. .SH SEE ALSO -.sp .LP \fBioctl\fR(2), \fBbind\fR(3SOCKET), \fBbyteorder\fR(3SOCKET), \fBconnect\fR(3SOCKET), \fBgethostbyname\fR(3NSL), \fBgetnetbyname\fR(3SOCKET), \fBgetprotobyname\fR(3SOCKET), \fBgetservbyname\fR(3SOCKET), -\fBgetsockopt\fR(3SOCKET), \fBsend\fR(3SOCKET), \fBsocket\fR(3SOCKET), -\fBarp\fR(7P), \fBicmp\fR(7P), \fBip\fR(7P), \fBtcp\fR(7P), \fBudp\fR(7P) +\fBgetsockopt\fR(3SOCKET), \fBsend\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBsocket\fR(3SOCKET), \fBarp\fR(7P), \fBicmp\fR(7P), \fBip\fR(7P), +\fBtcp\fR(7P), \fBudp\fR(7P) .sp .LP Network Information Center, \fIDDN Protocol Handbook\fR (3 vols.), Network Information Center, \fBSRI\fR International, Menlo Park, Calif., 1985. .SH NOTES -.sp .LP The Internet protocol support is subject to change as the Internet protocols develop. Users should not depend on details of the current implementation, but diff --git a/usr/src/man/man7p/inet6.7p b/usr/src/man/man7p/inet6.7p index cad3e96e7b..e439a7f498 100644 --- a/usr/src/man/man7p/inet6.7p +++ b/usr/src/man/man7p/inet6.7p @@ -14,7 +14,6 @@ inet6 \- Internet protocol family for Internet Protocol version 6 .fi .SH DESCRIPTION -.sp .LP The \fBinet6\fR protocol family implements a collection of protocols that are centered around the Internet Protocol version 6 (\fBIPv6\fR) and share a common @@ -24,7 +23,6 @@ and \fBSOCK_RAW\fR socket types, or the Transport Level Interface (\fBTLI\fR), where it supports the connectionless (\fBT_CLTS\fR) and connection oriented (\fBT_COTS_ORD\fR) service types. .SH PROTOCOLS -.sp .LP The Internet protocol family for \fBIPv6\fR included the Internet Protocol Version 6 (\fBIPv6\fR), the Neighbor Discovery Protocol (\fBNDP\fR), the @@ -162,7 +160,6 @@ The last 64 bits are the interface \fBID\fR. This will most often be the hardware address of the link in \fBIEEE EUI-64\fR format. .RE .SH ADDRESSING -.sp .LP \fBIPv6\fR addresses are sixteen byte quantities, stored in network byte order. The socket \fBAPI\fR uses the \fBsockaddr_in6\fR structure when passing @@ -242,7 +239,6 @@ In addition, the same port may be bound by two separate sockets if one is an numbers. These semantics apply when Internet family protocols are used using the \fBTLI\fR. .SH SOURCE ADDRESS SELECTION -.sp .LP IPv6 source address selection is done on a per destination basis, and utilizes a list of rules from which the best source address is selected from candidate @@ -373,14 +369,13 @@ If SB ^ D < SA ^ D, then prefer SB. Applications can override this algorithm by calling \fBbind\fR(3SOCKET) and specifying an address. .SH SEE ALSO -.sp .LP \fBioctl\fR(2), \fBbind\fR(3SOCKET), \fBconnect\fR(3SOCKET), \fBgetipnodebyaddr\fR(3SOCKET), \fBgetipnodebyname\fR(3SOCKET),\fBgetprotobyname\fR(3SOCKET), \fBgetservbyname\fR(3SOCKET), \fBgetsockopt\fR(3SOCKET), \fBinet\fR(3SOCKET), -\fBsend\fR(3SOCKET), \fBicmp6\fR(7P), \fBip6\fR(7P), \fBtcp\fR(7P), -\fBudp\fR(7P) +\fBsend\fR(3SOCKET), \fBsockaddr\fR(3SOCKET), +\fBicmp6\fR(7P), \fBip6\fR(7P), \fBtcp\fR(7P), \fBudp\fR(7P) .sp .LP Conta, A. and Deering, S., \fIInternet Control Message Protocol (ICMPv6) for @@ -403,7 +398,6 @@ Society. February 2003. Narten, T., and Draves, R. \fIRFC 3041, Privacy Extensions for Stateless Address Autoconfiguration in IPv6.\fR The Internet Society. January 2001. .SH NOTES -.sp .LP The \fBIPv6\fR support is subject to change as the Internet protocols develop. Users should not depend on details of the current implementation, but rather diff --git a/usr/src/man/man7p/pf_key.7p b/usr/src/man/man7p/pf_key.7p index 21e494ec3d..2e092973d2 100644 --- a/usr/src/man/man7p/pf_key.7p +++ b/usr/src/man/man7p/pf_key.7p @@ -19,7 +19,6 @@ pf_key \- Security association database interface .fi .SH DESCRIPTION -.sp .LP Keying information for IPsec security services is maintained in security association databases (\fBSADB\fRs). The security associations (\fBSA\fRs) are @@ -52,7 +51,6 @@ message and all extensions must be eight-byte aligned. An example message is the \fBGET\fR message, which requires the base header, the \fBSA \fRextension, and the \fBADDRESS_DST\fR extension. .SS "Messages" -.sp .LP Messages include: .sp @@ -162,7 +160,6 @@ Security Association Information Extension flags: .LP Extension headers include: .SS "Generic Extension Header" -.sp .in +2 .nf struct sadb_ext { @@ -173,7 +170,6 @@ struct sadb_ext { .in -2 .SS "Security Association Information Extension" -.sp .in +2 .nf struct sadb_sa { @@ -190,7 +186,6 @@ struct sadb_sa { .in -2 .SS "Lifetime Extension" -.sp .in +2 .nf struct sadb_lifetime { @@ -205,7 +200,6 @@ struct sadb_lifetime { .in -2 .SS "Address Extension" -.sp .in +2 .nf struct sadb_address { @@ -221,7 +215,6 @@ struct sadb_address { .in -2 .SS "Keying Material Extension" -.sp .in +2 .nf struct sadb_key { @@ -236,7 +229,6 @@ struct sadb_key { .in -2 .SS "Indentity Extension" -.sp .in +2 .nf struct sadb_ident { @@ -251,7 +243,6 @@ struct sadb_ident { .in -2 .SS "Sensitivity/Integrity Extension" -.sp .in +2 .nf struct sadb_sens { @@ -273,7 +264,6 @@ struct sadb_sens { .in -2 .SS "Proposal Extension" -.sp .in +2 .nf struct sadb_prop { @@ -288,7 +278,6 @@ struct sadb_prop { .in -2 .SS "Combination Instance for a Proposal" -.sp .in +2 .nf struct sadb_comb { @@ -313,7 +302,6 @@ struct sadb_comb { .in -2 .SS "Extended Combination" -.sp .in +2 .nf struct sadb_x_ecomb { @@ -334,7 +322,6 @@ struct sadb_x_ecomb { .in -2 .SS "Extended Combination Algorithm Descriptors" -.sp .in +2 .nf struct sadb_x_algdesc { @@ -349,7 +336,6 @@ struct sadb_x_algdesc { .in -2 .SS "Extended Register" -.sp .in +2 .nf struct sadb_x_ereg { @@ -361,7 +347,6 @@ struct sadb_x_ereg { .in -2 .SS "Key Management Cookie" -.sp .in +2 .nf struct sadb_x_kmc { @@ -375,7 +360,6 @@ struct sadb_x_kmc { .in -2 .SS "Supported Algorithms Extension" -.sp .in +2 .nf struct sadb_supported { @@ -387,7 +371,6 @@ struct sadb_supported { .in -2 .SS "Algorithm Instance" -.sp .in +2 .nf struct sadb_alg { @@ -401,7 +384,6 @@ struct sadb_alg { .in -2 .SS "SPI Extension Range" -.sp .in +2 .nf struct sadb_spirange { @@ -415,7 +397,6 @@ struct sadb_spirange { .in -2 .SS "Security Association Pair Extension" -.sp .in +2 .nf struct sadb_x_pair { @@ -427,7 +408,6 @@ struct sadb_x_pair { .in -2 .SS "Message Use and Behavior" -.sp .LP Each message has a behavior. A behavior is defined as where the initial message travels, for example, user to kernel, and what subsequent actions are expected @@ -529,7 +509,6 @@ Message exceeds the maximum length allowed. .LP The following are examples of message use and behavior: .SS "\fBSADB_GETSPI\fR" -.sp .LP Send a \fBSADB_GETSPI\fR message from a user process to the kernel. .sp @@ -550,7 +529,6 @@ The kernel returns the \fBSADB_GETSPI\fR message to all listening processes. .in -2 .SS "\fBSADB_UPDATE\fR" -.sp .LP Send a \fBSADB_UPDATE\fR message from a user process to the kernel. .sp @@ -579,7 +557,6 @@ security association contained in that extension. The resulting security association "pair" can be updated or as a single entity using the \fBSADB_X_UPDATEPAIR\fR or \fBSADB_X_DELPAIR\fR message types. .SS "\fBSADB_ADD\fR" -.sp .LP Send a \fBSADB_ADD\fR message from a user process to the kernel. .sp @@ -602,7 +579,6 @@ The kernel returns the \fBSADB_ADD\fR message to all listening processes. .in -2 .SS "\fBSADB_X_UPDATEPAIR\fR" -.sp .LP Send a \fBSADB_X_UPDATEPAIR\fR message from a user process to the kernel. This message type is used to update the lifetime values of a security @@ -616,7 +592,6 @@ with. .in -2 .SS "\fBSADB_DELETE | SADB_X_DELPAIR\fR" -.sp .LP Send a \fBSADB_DELETE\fR message from a user process to the kernel. The \fBSADB_X_DELPAIR\fR message type will request deletion of the security @@ -639,7 +614,6 @@ The kernel returns the \fBSADB_DELETE\fR message to all listening processes. .in -2 .SS "\fBSADB_GET\fR" -.sp .LP Send a \fBSADB_GET\fR message from a user process to the kernel. .sp @@ -662,7 +636,6 @@ The kernel returns the \fBSADB_GET\fR message to the socket that sent the .in -2 .SS "\fBSADB_ACQUIRE\fR" -.sp .LP The kernel sends a \fBSADB_ACQUIRE\fR message to registered sockets. Note that any \fBGETSPI\fR, \fBADD\fR, or \fBUPDATE\fR calls in reaction to an @@ -702,7 +675,6 @@ If key management fails, send an \fBSADB_ACQUIRE\fR to indicate failure. .in -2 .SS "\fBSADB_X_INVERSE_ACQUIRE\fR" -.sp .LP For inbound Key Management processing, a Key Management application may wish to consult the kernel for its policy. The application should send to the kernel: @@ -725,7 +697,6 @@ The kernel returns a message similar to a kernel-generated extended ACQUIRE: .in -2 .SS "\fBSADB_REGISTER\fR" -.sp .LP Send a \fBSADB_REGISTER\fR message from a user process to the kernel. .sp @@ -764,7 +735,6 @@ extended ACQUIREs. Which returns a series of SADB_REGISTER replies (one for each security protocol registered) from the kernel. .SS "\fBSADB_EXPIRE\fR" -.sp .LP The kernel sends a \fBSADB_EXPIRE\fR message to all listeners when the soft limit of a security association has been expired. @@ -776,7 +746,6 @@ limit of a security association has been expired. .in -2 .SS "\fBSADB_FLUSH\fR" -.sp .LP Send a \fBSADB_FLUSH\fR message from a user process to the kernel. .sp @@ -797,7 +766,6 @@ The kernel returns the \fBSADB_FLUSH\fR message to all listening sockets. .in -2 .SS "\fBSADB_DUMP\fR" -.sp .LP Send a \fBSADB_DUMP\fR message from a user process to the kernel. .sp @@ -831,7 +799,6 @@ To mark the end of a dump a single base header arrives with its .in -2 .SS "\fBSADB_X_PROMISC\fR" -.sp .LP Send a \fBSADB_X_PROMISC\fR message from a user process to the kernel. .sp @@ -852,7 +819,6 @@ The kernel returns the \fBSADB_X_PROMISC\fR message to all listening processes. .in -2 .SH DIAGNOSTICS -.sp .LP The message returning from the kernel will contain a diagnostic value in the base message header, the diagnostic value will indicate if action requested by @@ -970,7 +936,6 @@ Diagnostic Values: .in -2 .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -985,16 +950,15 @@ Interface Stability Evolving .TE .SH SEE ALSO -.sp .LP -\fBin.iked\fR(1M), \fBipseckey\fR(1M), \fBipsec\fR(7P), \fBipsecah\fR(7P), +\fBin.iked\fR(1M), \fBipseckey\fR(1M), \fBsockaddr\fR(3SOCKET), +\fBipsec\fR(7P), \fBipsecah\fR(7P), \fBipsecesp\fR(7P), \fBroute\fR(7P), \fBudp\fR(7P) .sp .LP McDonald, D.L., Metz, C.W., and Phan, B.G., \fIRFC 2367, PF_KEY Key Management API, Version 2\fR, The Internet Society, July 1998. .SH NOTES -.sp .LP Time-based lifetimes may not expire with exact precision in seconds because kernel load may affect the aging of \fBSA\fR's. diff --git a/usr/src/man/man7p/route.7p b/usr/src/man/man7p/route.7p index 0209e580ad..ba193fef11 100644 --- a/usr/src/man/man7p/route.7p +++ b/usr/src/man/man7p/route.7p @@ -22,7 +22,6 @@ route \- kernel packet forwarding database .fi .SH DESCRIPTION -.sp .LP UNIX provides some packet routing facilities. The kernel maintains a routing information database, which is used in selecting the appropriate network @@ -208,7 +207,6 @@ that configure interfaces and wish to wait until the interface is ready can wait until \fBRTM_IFINFO\fR is returned and \fBSIOCGLIFFLAGS\fR shows that \fBIFF_DUPLICATE\fR is not set. .SS "Messages" -.sp .LP User processes can obtain information about the routing entry to a specific destination by using a \fBRTM_GET\fR message. @@ -323,12 +321,10 @@ struct rt_metrics { .in -2 .SH SEE ALSO -.sp .LP \fBioctl\fR(2), \fBsetsockopt\fR(3SOCKET), \fBshutdown\fR(3SOCKET), -\fBrouting\fR(7P) +\fBsockaddr\fR(3SOCKET), \fBrouting\fR(7P) .SH NOTES -.sp .LP Some of the metrics might not be implemented and return zero. The implemented metrics are set in \fBrtm_inits\fR. diff --git a/usr/src/pkg/manifests/system-library.man3socket.inc b/usr/src/pkg/manifests/system-library.man3socket.inc index 44a8d7793e..b3f8ca66d9 100644 --- a/usr/src/pkg/manifests/system-library.man3socket.inc +++ b/usr/src/pkg/manifests/system-library.man3socket.inc @@ -49,6 +49,7 @@ file path=usr/share/man/man3socket/sctp_send.3socket file path=usr/share/man/man3socket/sctp_sendmsg.3socket file path=usr/share/man/man3socket/send.3socket file path=usr/share/man/man3socket/shutdown.3socket +file path=usr/share/man/man3socket/sockaddr.3socket file path=usr/share/man/man3socket/socket.3socket file path=usr/share/man/man3socket/socketpair.3socket file path=usr/share/man/man3socket/spray.3socket @@ -181,3 +182,11 @@ link path=usr/share/man/man3socket/setsockopt.3socket \ target=getsockopt.3socket link path=usr/share/man/man3socket/setsourcefilter.3socket \ target=getsourcefilter.3socket +link path=usr/share/man/man3socket/sockaddr_dl.3socket target=sockaddr.3socket +link path=usr/share/man/man3socket/sockaddr_in.3socket target=sockaddr.3socket +link path=usr/share/man/man3socket/sockaddr_in6.3socket \ + target=sockaddr.3socket +link path=usr/share/man/man3socket/sockaddr_ll.3socket target=sockaddr.3socket +link path=usr/share/man/man3socket/sockaddr_storage.3socket \ + target=sockaddr.3socket +link path=usr/share/man/man3socket/sockaddr_un.3socket target=sockaddr.3socket diff --git a/usr/src/uts/common/smbsrv/ndl/netlogon.ndl b/usr/src/uts/common/smbsrv/ndl/netlogon.ndl index 561928440f..de6c19049b 100644 --- a/usr/src/uts/common/smbsrv/ndl/netlogon.ndl +++ b/usr/src/uts/common/smbsrv/ndl/netlogon.ndl @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _MLSVC_NETR_NDL_ @@ -57,6 +58,17 @@ #define NETR_OPNUM_DatabaseRedo 0x11 #define NETR_OPNUM_LogonControl2Ex 0x12 #define NETR_OPNUM_TrustDomainList 0x13 +#define NETR_OPNUM_DsrGetDcName 0x14 +#define NETR_OPNUM_LogonGetCapabilities 0x15 +#define NETR_OPNUM_LogonSetServiceBits 0x16 +#define NETR_OPNUM_LogonGetTrustRid 0x17 +#define NETR_OPNUM_LogonComputeServerDigest 0x18 +#define NETR_OPNUM_LogonComputeClientDigest 0x19 +#define NETR_OPNUM_ServerAuthenticate3 0x1A +#define NETR_OPNUM_DsrGetDcNameEx 0x1B +#define NETR_OPNUM_DsrGetSiteName 0x1C +#define NETR_OPNUM_LogonGetDomainInfo 0x1D +#define NETR_OPNUM_ServerPasswordSet2 0x1E struct netr_sid { @@ -134,17 +146,25 @@ struct OLD_LARGE_INTEGER { }; typedef struct OLD_LARGE_INTEGER netr_int64_t; +struct CYPHER_BLOCK { + BYTE data[8]; +}; struct OWF_PASSWORD { BYTE data[16]; }; typedef struct OWF_PASSWORD netr_owf_password_t; - -struct CYPHER_BLOCK { - BYTE data[8]; +/* + * NL_TRUST_PASSWORD + * See also: samr_user_password + */ +#define NETR_TRUST_PWLEN 256 +struct netr_trust_password { + WORD Buffer[NETR_TRUST_PWLEN]; + DWORD Length; }; - +typedef struct netr_trust_password netr_trust_password_t; struct USER_SESSION_KEY { struct CYPHER_BLOCK data[2]; @@ -198,10 +218,21 @@ OPERATION(NETR_OPNUM_ServerPasswordSet) struct netr_PasswordSet { IN LPTSTR servername; IN REFERENCE LPTSTR account_name; - IN WORD account_type; + IN WORD sec_chan_type; + IN REFERENCE LPTSTR hostname; + INOUT struct netr_authenticator auth; + IN netr_owf_password_t owf_password; + OUT DWORD status; +}; + +OPERATION(NETR_OPNUM_ServerPasswordSet2) +struct netr_PasswordSet2 { + IN LPTSTR servername; + IN REFERENCE LPTSTR account_name; + IN WORD sec_chan_type; IN REFERENCE LPTSTR hostname; INOUT struct netr_authenticator auth; - IN netr_owf_password_t uas_new_password; + IN netr_trust_password_t trust_password; OUT DWORD status; }; @@ -398,6 +429,8 @@ union netr_interface { struct netr_SamLogoff SamLogoff; CASE(NETR_OPNUM_ServerPasswordSet) struct netr_PasswordSet PasswordSet; + CASE(NETR_OPNUM_ServerPasswordSet2) + struct netr_PasswordSet2 PasswordSet2; }; typedef union netr_interface netr_interface_t; EXTERNTYPEINFO(netr_interface) diff --git a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl index 5fe7a0f203..2e4a932a5b 100644 --- a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl +++ b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl @@ -18,8 +18,10 @@ * * CDDL HEADER END */ + /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ #ifndef _MLSVC_SAM_NDL_ @@ -89,10 +91,10 @@ #define SAMR_OPNUM_AddMultipleAliasMembers 0x34 #define SAMR_OPNUM_RemoveMultipleAliasMembers 0x35 #define SAMR_OPNUM_ChangeUserOemPassword 0x36 -#define SAMR_OPNUM_ChangeUserPasswd 0x37 /* UnicodePasswd */ +#define SAMR_OPNUM_ChangePasswordUser2 0x37 /* UnicodePasswd */ #define SAMR_OPNUM_GetDomainPwInfo 0x38 #define SAMR_OPNUM_Connect2 0x39 /* SamrConnect2 */ -#define SAMR_OPNUM_SetUserInfo 0x3a +#define SAMR_OPNUM_SetUserInfo 0x3a /* SetInfoUser2 */ #define SAMR_OPNUM_SetBootKeyInformation 0x3b #define SAMR_OPNUM_GetBootKeyInformation 0x3c #define SAMR_OPNUM_Connect3 0x3d /* NotUsedOnWire */ @@ -111,15 +113,6 @@ /* - * UNION_INFO_ENT is intended to simplify adding new entries to a union. - * If the entry structures are named using the form samr_QueryUserInfoX, - * where X is the sitch_value, you can just add a single line. Note - * that you must also update the fixup function in mlsvc_sam.c. - */ -#define UNION_INFO_ENT(N,NAME) CASE(N) struct NAME##N info##N - - -/* * Sam account flags used when creating an account. These flags seem * to be very similar to the USER_INFO_X flags (UF_XXX) in lmaccess.h * but the values are different. @@ -181,6 +174,7 @@ #define SAMR_USER_ALL_PRIVATEDATA 0x04000000 #define SAMR_USER_ALL_PASSWORDEXPIRED 0x08000000 #define SAMR_USER_ALL_SECURITYDESCRIPTOR 0x10000000 +#define SAMR_USER_ALL_OWF_PASSWORD 0x20000000 #define SAMR_USER_ALL_UNDEFINED_MASK 0xC0000000 /* @@ -204,6 +198,7 @@ /* * Definition for a SID. The ndl compiler does not allow a typedef of * a structure containing variable size members. + * Note: cast compatible with smb_sid_t, and code depends on that. */ struct samr_sid { BYTE Revision; @@ -235,6 +230,7 @@ struct samr_sd { typedef struct samr_sd samr_sd_t; /* + * See RPC_STRING in the MS IDL. * Definition for a string. The length and allosize should be set to * twice the string length (i.e. strlen(str) * 2). The runtime code * will perform the appropriate string to a wide-char conversions, @@ -355,9 +351,33 @@ struct samr_logon_hours_all { BYTE *hours; }; -struct samr_oem_password { - BYTE password[512]; - DWORD length; +/* + * SAMPR_USER_PASSWORD (in the MS Net API) or + * struct samr_user_password (internal use) is + * the "clear" form of struct samr_encr_passwd + * (SAMPR_ENCRYPTED_USER_PASSWORD in MS Net). + * It's not used by ndrgen, but is declared here + * to help clarify the relationship between these, + * and for the benefit of our client-side code. + */ +#ifndef NDRGEN +#define SAMR_USER_PWLEN 256 +struct samr_user_password { + smb_wchar_t Buffer[SAMR_USER_PWLEN]; + DWORD Length; +}; +#endif /* NDRGEN */ + +/* SAMPR_ENCRYPTED_USER_PASSWORD */ +#define SAMR_ENCR_PWLEN 516 /* sizeof samr_user_password */ +struct samr_encr_passwd { + BYTE data[SAMR_ENCR_PWLEN]; +}; + +/* ENCRYPTED_NT_OWF_PASSWORD */ +#define SAMR_PWHASH_LEN 16 +struct samr_encr_hash { + BYTE data[SAMR_PWHASH_LEN]; }; /* @@ -437,10 +457,16 @@ OPERATION(SAMR_OPNUM_Connect5) struct samr_Connect5 { IN LPTSTR servername; IN DWORD access_mask; - INOUT DWORD unknown2_00000001; - INOUT DWORD unknown3_00000001; - INOUT DWORD unknown4_00000003; - INOUT DWORD unknown5_00000000; + /* + * This should be a union, but instead this is + * done this way because unions are hard to + * express in this RPC implementation. + */ + INOUT DWORD unknown2_00000001; /* V1 */ + INOUT DWORD unknown3_00000001; /* V1 */ + /* SAMPR_REVISION_INFO_V1 */ + INOUT DWORD unknown4_00000003; /* Revision */ + INOUT DWORD unknown5_00000000; /* SupportedFeatures */ OUT samr_handle_t handle; OUT DWORD status; }; @@ -895,7 +921,7 @@ struct samr_QueryUserInfo9 { struct samr_QueryUserInfo16 { - DWORD unknown; + DWORD UserAccountControl; }; /* @@ -937,6 +963,7 @@ struct samr_QueryUserInfo21 { BYTE PrivateDataSensitive; }; +/* See also: fixup_samr_QueryUserInfo() */ union QueryUserInfo_result_u { UNION_INFO_ENT(1,samr_QueryUserInfo); UNION_INFO_ENT(6,samr_QueryUserInfo); @@ -1204,27 +1231,20 @@ struct samr_CreateUser { /* *********************************************************************** - * ChangeUserPasswd + * ChangePasswordUser2 - See: + * SamrUnicodeChangePasswordUser2 [MS-SAMR 3.1.5.10.3] *********************************************************************** */ -struct samr_newpasswd { - BYTE data[516]; -}; - - -struct samr_oldpasswd { - BYTE data[16]; -}; - -OPERATION(SAMR_OPNUM_ChangeUserPasswd) -struct samr_ChangeUserPasswd { - IN LPTSTR servername; - IN LPTSTR username; - IN struct samr_newpasswd *nt_newpasswd; - IN struct samr_oldpasswd *nt_oldpasswd; - IN struct samr_newpasswd *lm_newpasswd; - IN struct samr_oldpasswd *lm_oldpasswd; +OPERATION(SAMR_OPNUM_ChangePasswordUser2) +struct samr_ChangePasswordUser2 { + IN samr_string_t *servername; + IN REF samr_string_t *username; + IN struct samr_encr_passwd *nt_newpw; + IN struct samr_encr_hash *nt_oldpw; + IN BYTE lm_present; + IN struct samr_encr_passwd *lm_newpw; + IN struct samr_encr_hash *lm_oldpw; OUT DWORD status; }; @@ -1245,172 +1265,112 @@ struct samr_GetDomainPwInfo { /* *********************************************************************** * SetUserInfo - * - * +++ 20 byte user handle and the union switch_value +++ - * 00 00 00 00 77 F2 DD D5 66 48 D4 11 AD 5F D1 CD - * 18 43 7A DF 17 00 17 00 - * - * +++ 14 dwords (56 bytes) of zeros +++ - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 - * - * +++ 9 sets of something - 72 bytes +++ - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * 00 00 02 00 D0 04 8A 77 - * - * +++ 9 DWORD zeros +++ - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 - * - * +++ miscellaneous +++ - * 01 02 00 00 - * 80 00 00 00 - * FA 27 F8 09 - * A8 00 00 00 70 F1 14 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 - * - * +++ encrypted password buffer - 512 bytes +++ - * 76 68 E8 AA 23 4F 62 C4 81 4E 30 B8 92 29 66 B9 - * 12 FF 3A 84 82 3A 55 0F C7 18 EA 56 86 50 D7 C5 - * 43 BA 9C F8 32 D4 E0 15 74 A1 6F E1 59 C2 F2 95 - * 53 A9 F2 68 9F 7F 29 B9 88 4C 65 A5 C1 DC 0B 44 - * B8 3C ED 74 D1 6A F7 09 66 97 94 6B 2C 3A A5 88 - * 39 34 C6 FE 24 59 30 2D CF 6D 7F D5 EC B1 9A 84 - * E6 57 96 29 40 32 FB 62 9D 93 E2 BE D8 A3 74 88 - * 8B 85 BC A0 76 D6 C9 DB 8C AF 81 BD 8A F0 08 8D - * 23 B0 52 FD 69 DE EF A1 36 E5 30 19 BD DA 67 A3 - * 81 BD 3F D0 2A A2 8F 60 62 B0 8D 34 9E A4 4F 20 - * 4E 79 93 82 58 A8 E5 6F 7A DC 12 13 33 E6 74 02 - * 4C 32 F9 FC 1A E1 C5 0D E2 CC 36 8D FC 72 87 DD - * 6C 44 E3 6F 4B FD 46 10 08 89 E5 64 B8 27 14 83 - * E7 08 DE CF 69 C7 E1 40 63 DF CB 67 95 73 03 1B - * CA 99 E1 1B 53 2A 89 6B 30 39 CD 5C DF A0 8A 1C - * 4E 50 74 7C 6D 3D E7 EA E9 B2 97 DD 38 7B DA EC - * 1A AD DA CE C4 58 9B 29 F3 6D 30 70 4E 63 6D 84 - * DB DC 5B CD 9A 4E 57 9C E4 65 5D 4F 76 E3 C7 52 - * 8B 3B 20 0A 3B 4C 4B B1 2E 5B 4D AB BA 2F 45 6A - * CA 17 AD 9F C0 B2 07 FB 56 7F E4 3F 9F D4 C6 8C - * A1 05 BF 53 42 1E 67 F4 57 54 E3 2C 38 CF E1 94 - * 75 69 F7 4E 5C 74 CC B3 FD EF 73 3F D5 28 22 EC - * 9B 40 E1 1D 65 44 7C BB 69 88 57 10 05 3A C5 48 - * 8E 4F 77 DB 1A 5C 49 9C D5 06 00 AC 79 BC 7E 89 - * B0 01 66 70 88 A2 E5 DF 96 DC 75 98 10 12 45 02 - * 33 35 6C DF 74 8B 14 2F 26 C6 FD 7A B4 D0 A6 7D - * DE 2B 13 44 EF 34 46 4D 9D 3E C3 75 BC 11 B4 41 - * 27 58 25 1E AF AA F0 BB DA 27 7A 1E AE 81 1A 78 - * 44 19 DE FC C4 7C 4E 32 44 F7 57 2A 41 A2 85 DC - * C0 AD 5D 6B 58 FD 2E 75 25 B9 F2 B6 19 82 E5 0E - * B6 69 0D C1 27 A9 B6 40 A6 50 49 E5 CB 17 98 65 - * 88 18 CA E4 1D 2E 20 F7 DE 8E 7D F2 9D A5 6B CD - * - * D6 79 45 71 - * - * +++ table of 9 things +++ - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * 01 00 00 00 00 00 00 00 00 00 00 00 - * - * +++ miscellaneous +++ - * EC 04 00 00 00 00 00 00 15 00 00 00 - * FF FF FF FF FF FF FF FF FF FF FF FF - * FF FF FF FF FF FF FF FF FF - * + * [MS-SAMR] SamrSetInformationUser2 *********************************************************************** */ -#define SAMR_SET_USER_INFO_23 23 -#define SAMR_SET_USER_DATA_SZ 516 +/* USER_CONTROL_INFORMATION */ +struct samr_SetUserInfo16 { + DWORD UserAccountControl; +}; + + +/* + * samr_SetUserInfo21, a.k.a + * SAMR_USER_ALL_INFORMATION + * + * We now know this is the same as samr_QueryUserInfo21 + * Could merge, except for the samr_vcbuf_t mess. + */ + +#define SAMR_SET_USER_INFO_21 21 + +struct samr_SetUserInfo21 { + samr_quad_t LastLogon; + samr_quad_t LastLogoff; + samr_quad_t PasswordLastSet; + samr_quad_t AccountExpires; + samr_quad_t PasswordCanChange; + samr_quad_t PasswordMustChange; + + samr_vcbuf_t UserName; + samr_vcbuf_t FullName; + samr_vcbuf_t HomeDirectory; + samr_vcbuf_t HomeDirectoryDrive; + samr_vcbuf_t ScriptPath; + samr_vcbuf_t ProfilePath; + samr_vcbuf_t AdminComment; + samr_vcbuf_t WorkStations; + samr_vcbuf_t UserComment; + samr_vcbuf_t Parameters; + + struct samr_short_blob LmOwfPassword; + struct samr_short_blob NtOwfPassword; + samr_vcbuf_t PrivateData; + samr_sd_t SecurityDescriptor; + + DWORD UserId; /* RID */ + DWORD PrimaryGroupId; + DWORD UserAccountControl; + DWORD WhichFields; -struct samr_SetUserInfo23 { - samr_quad_t logon_time; /* 00 00 00 00 00 00 00 00 */ - samr_quad_t logoff_time; /* 00 00 00 00 00 00 00 00 */ - samr_quad_t kickoff_time; /* 00 00 00 00 00 00 00 00 */ - samr_quad_t passwd_last_set_time; /* 00 00 00 00 00 00 00 00 */ - samr_quad_t passwd_can_change_time; /* 00 00 00 00 00 00 00 00 */ - samr_quad_t passwd_must_change_time; /* 00 00 00 00 00 00 00 00 */ - - samr_vcbuf_t user_name; /* 00 00 00 00 00 00 00 00 */ - samr_vcbuf_t full_name; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t home_dir; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t home_drive; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t logon_script; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t profile_path; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t acct_desc; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t workstations; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t unknown1; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t unknown2; /* 00 00 02 00 D0 04 8A 77 */ - samr_vcbuf_t lm_password; /* 00 00 00 00 00 00 00 00 */ - samr_vcbuf_t nt_password; /* 00 00 00 00 00 00 00 00 */ - samr_vcbuf_t unknown3; /* 00 00 00 00 00 00 00 00 */ - - struct samr_sd sd; /* 00 00 00 00 00 00 00 00 */ - DWORD user_rid; /* 00 00 00 00 */ - DWORD group_rid; /* 01 02 00 00 */ - DWORD acct_info; /* 80 00 00 00 */ - DWORD flags; /* FA 27 F8 09 */ - struct samr_logon_info logon_info; /* A8 00 00 00 70 F1 14 00->0xFF */ /* - * The following 12 bytes are encoded in Ethereal as: - * - * WORD bad_pwd_count; - * WORD logon_count; - * - * WORD country; (default 0) - * WORD codepage; - * - * BYTE nt_pwd_set; - * BYTE lm_pwd_set; - * BYTE expired_flag; - * BYTE unknown_char; + * This should be samr_logon_hours_all, but apparently + * ndrgen doesn't get that quite right, so instead, the + * client-side code patches this up. */ - DWORD unknown4_zero; /* 00 00 00 00 */ - DWORD unknown5_zero; /* 00 00 00 00 */ - DWORD unknown6_zero; /* 00 00 00 00 */ - BYTE password[SAMR_SET_USER_DATA_SZ]; + struct samr_logon_info LogonHours; + + WORD BadPasswordCount; + WORD LogonCount; + WORD CountryCode; + WORD CodePage; + BYTE LmPasswordPresent; + BYTE NtPasswordPresent; + BYTE PasswordExpired; + BYTE PrivateDataSensitive; +}; + +/* + * SAMPR_USER_INTERNAL4_INFORMATION + * UserInternal4Information (23) + */ +#define SAMR_SET_USER_INFO_23 23 +struct samr_SetUserInfo23 { + struct samr_SetUserInfo21 info21; + struct samr_encr_passwd encr_pw; +}; + +/* + * SAMPR_USER_INTERNAL5_INFORMATION + * UserInternal5Information (24) + */ +#define SAMR_SET_USER_INFO_24 24 +struct samr_SetUserInfo24 { + struct samr_encr_passwd encr_pw; + BYTE password_expired; }; union samr_SetUserInfo_u { + UNION_INFO_ENT(16,samr_SetUserInfo); + UNION_INFO_ENT(21,samr_SetUserInfo); UNION_INFO_ENT(23,samr_SetUserInfo); - DEFAULT char *nullptr; + UNION_INFO_ENT(24,samr_SetUserInfo); + DEFAULT DWORD nothing; }; - struct samr_SetUserInfo_s { - WORD index; + WORD info_level; WORD switch_value; SWITCH(switch_value) union samr_SetUserInfo_u ru; }; - -/* - IN DWORD unknown_04EC; - IN DWORD unknown_zero; - IN DWORD logon_bitmap_size; - IN BYTE logon_bitmap[SAMR_SET_USER_HOURS_SZ]; -*/ OPERATION(SAMR_OPNUM_SetUserInfo) struct samr_SetUserInfo { IN samr_handle_t user_handle; IN struct samr_SetUserInfo_s info; - IN struct samr_logon_hours logon_hours; OUT DWORD status; }; @@ -1458,8 +1418,8 @@ union samr_interface { struct samr_GetUserPwInfo GetUserPwInfo; CASE(SAMR_OPNUM_CreateUser) struct samr_CreateUser CreateUser; - CASE(SAMR_OPNUM_ChangeUserPasswd) - struct samr_ChangeUserPasswd ChangeUserPasswd; + CASE(SAMR_OPNUM_ChangePasswordUser2) + struct samr_ChangePasswordUser2 ChangePasswordUser2; CASE(SAMR_OPNUM_GetDomainPwInfo) struct samr_GetDomainPwInfo GetDomainPwInfo; CASE(SAMR_OPNUM_Connect2) |