1b3700b07SGordon Ross /* 2b3700b07SGordon Ross * This file and its contents are supplied under the terms of the 3b3700b07SGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0. 4b3700b07SGordon Ross * You may only use this file in accordance with the terms of version 5b3700b07SGordon Ross * 1.0 of the CDDL. 6b3700b07SGordon Ross * 7b3700b07SGordon Ross * A full copy of the text of the CDDL should have accompanied this 8b3700b07SGordon Ross * source. A copy of the CDDL is also available via the Internet at 9b3700b07SGordon Ross * http://www.illumos.org/license/CDDL. 10b3700b07SGordon Ross */ 11b3700b07SGordon Ross 12b3700b07SGordon Ross /* 13b3700b07SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 14b3700b07SGordon Ross */ 15b3700b07SGordon Ross 16b3700b07SGordon Ross 17b3700b07SGordon Ross #include <stdio.h> 18b3700b07SGordon Ross #include <stdlib.h> 19b3700b07SGordon Ross #include <stdarg.h> 20b3700b07SGordon Ross #include <string.h> 21b3700b07SGordon Ross #include <syslog.h> 22b3700b07SGordon Ross #include <rpc/rpc.h> 23b3700b07SGordon Ross #include <sys/uuid.h> 24b3700b07SGordon Ross #include <smb/ntstatus.h> 25b3700b07SGordon Ross #include <synch.h> 26b3700b07SGordon Ross #include <thread.h> 27b3700b07SGordon Ross #include <arpa/inet.h> 28b3700b07SGordon Ross #include <uuid/uuid.h> 29b3700b07SGordon Ross 30b3700b07SGordon Ross #include "idmapd.h" 31b3700b07SGordon Ross #include "libadutils.h" 32b3700b07SGordon Ross #include "dsgetdc.h" 33b3700b07SGordon Ross #include "ads_priv.h" 34b3700b07SGordon Ross 35b3700b07SGordon Ross void adspriv_program_1(struct svc_req *, register SVCXPRT *); 36b3700b07SGordon Ross 37b3700b07SGordon Ross SVCXPRT *dcl_xprt = NULL; 38b3700b07SGordon Ross 39b3700b07SGordon Ross void 40b3700b07SGordon Ross init_dc_locator(void) 41b3700b07SGordon Ross { 42b3700b07SGordon Ross int connmaxrec = 32 * 1024; 43b3700b07SGordon Ross 44b3700b07SGordon Ross dcl_xprt = svc_door_create(adspriv_program_1, 45b3700b07SGordon Ross ADSPRIV_PROGRAM, ADSPRIV_V1, connmaxrec); 46b3700b07SGordon Ross if (dcl_xprt == NULL) { 47b3700b07SGordon Ross syslog(LOG_ERR, "unable to create door RPC service"); 48b3700b07SGordon Ross return; 49b3700b07SGordon Ross } 50b3700b07SGordon Ross 51b3700b07SGordon Ross if (!svc_control(dcl_xprt, SVCSET_CONNMAXREC, &connmaxrec)) { 52b3700b07SGordon Ross syslog(LOG_ERR, "unable to limit RPC request size"); 53b3700b07SGordon Ross } 54b3700b07SGordon Ross } 55b3700b07SGordon Ross 56b3700b07SGordon Ross void 57b3700b07SGordon Ross fini_dc_locator(void) 58b3700b07SGordon Ross { 59b3700b07SGordon Ross if (dcl_xprt != NULL) 60b3700b07SGordon Ross svc_destroy(dcl_xprt); 61b3700b07SGordon Ross } 62b3700b07SGordon Ross 63b3700b07SGordon Ross /* 64b3700b07SGordon Ross * Functions called by the (generated) adspriv_srv.c 65b3700b07SGordon Ross */ 66b3700b07SGordon Ross 67b3700b07SGordon Ross /* ARGSUSED */ 68b3700b07SGordon Ross bool_t 69b3700b07SGordon Ross adspriv_null_1_svc(void *result, struct svc_req *rqstp) 70b3700b07SGordon Ross { 71b3700b07SGordon Ross return (TRUE); 72b3700b07SGordon Ross } 73b3700b07SGordon Ross 74b3700b07SGordon Ross /* ARGSUSED */ 75b3700b07SGordon Ross bool_t 76b3700b07SGordon Ross adspriv_forcerediscovery_1_svc( 77b3700b07SGordon Ross DsForceRediscoveryArgs args, 78b3700b07SGordon Ross int *res, 79b3700b07SGordon Ross struct svc_req *sreq) 80b3700b07SGordon Ross { 81b3700b07SGordon Ross /* Ignoring args for now. */ 82b3700b07SGordon Ross 83b3700b07SGordon Ross idmap_cfg_force_rediscovery(); 84b3700b07SGordon Ross *res = 0; 85b3700b07SGordon Ross 86b3700b07SGordon Ross return (TRUE); 87b3700b07SGordon Ross } 88b3700b07SGordon Ross 89b3700b07SGordon Ross 90b3700b07SGordon Ross /* ARGSUSED */ 91b3700b07SGordon Ross bool_t 92b3700b07SGordon Ross adspriv_getdcname_1_svc( 93b3700b07SGordon Ross DsGetDcNameArgs args, 94b3700b07SGordon Ross DsGetDcNameRes *res, 95b3700b07SGordon Ross struct svc_req *sreq) 96b3700b07SGordon Ross { 97b3700b07SGordon Ross uuid_t uuid; 98b3700b07SGordon Ross adspriv_dcinfo *dci; 99b3700b07SGordon Ross idmap_pg_config_t *pgcfg; 100b3700b07SGordon Ross ad_disc_ds_t *ds; 101b3700b07SGordon Ross char *s; 102b3700b07SGordon Ross 103b3700b07SGordon Ross /* Init */ 104b3700b07SGordon Ross (void) memset(res, 0, sizeof (*res)); 105b3700b07SGordon Ross res->status = 0; 106b3700b07SGordon Ross dci = &res->DsGetDcNameRes_u.res0; 107b3700b07SGordon Ross 108b3700b07SGordon Ross if (args.Flags & DS_FORCE_REDISCOVERY) 109b3700b07SGordon Ross idmap_cfg_force_rediscovery(); 110b3700b07SGordon Ross 111b3700b07SGordon Ross /* 112b3700b07SGordon Ross * We normally should wait if discovery is running. 113b3700b07SGordon Ross * Sort of mis-using the background flag as a way to 114b3700b07SGordon Ross * skip the wait, until we really do background disc. 115b3700b07SGordon Ross */ 116b3700b07SGordon Ross if ((args.Flags & DS_BACKGROUND_ONLY) == 0) { 117b3700b07SGordon Ross timespec_t tv = { 15, 0 }; 118b3700b07SGordon Ross int rc = 0; 119b3700b07SGordon Ross int waited = 0; 120b3700b07SGordon Ross 121b3700b07SGordon Ross (void) mutex_lock(&_idmapdstate.addisc_lk); 122b3700b07SGordon Ross 123b3700b07SGordon Ross if (_idmapdstate.addisc_st != 0) 124b3700b07SGordon Ross idmapdlog(LOG_DEBUG, "getdcname wait begin"); 125b3700b07SGordon Ross 126b3700b07SGordon Ross while (_idmapdstate.addisc_st != 0) { 127b3700b07SGordon Ross waited++; 128b3700b07SGordon Ross rc = cond_reltimedwait(&_idmapdstate.addisc_cv, 129b3700b07SGordon Ross &_idmapdstate.addisc_lk, &tv); 130b3700b07SGordon Ross if (rc == ETIME) 131b3700b07SGordon Ross break; 132b3700b07SGordon Ross } 133b3700b07SGordon Ross (void) mutex_unlock(&_idmapdstate.addisc_lk); 134b3700b07SGordon Ross 135b3700b07SGordon Ross if (rc == ETIME) { 136b3700b07SGordon Ross /* Caller will replace this with DC not found. */ 137b3700b07SGordon Ross idmapdlog(LOG_ERR, "getdcname timeout"); 138b3700b07SGordon Ross res->status = NT_STATUS_CANT_WAIT; 139b3700b07SGordon Ross return (TRUE); 140b3700b07SGordon Ross } 141b3700b07SGordon Ross if (waited) { 142b3700b07SGordon Ross idmapdlog(LOG_DEBUG, "getdcname wait done"); 143b3700b07SGordon Ross } 144b3700b07SGordon Ross } 145b3700b07SGordon Ross 146b3700b07SGordon Ross RDLOCK_CONFIG(); 147b3700b07SGordon Ross pgcfg = &_idmapdstate.cfg->pgcfg; 148b3700b07SGordon Ross 149b3700b07SGordon Ross if (pgcfg->domain_name == NULL) { 150b3700b07SGordon Ross res->status = NT_STATUS_INVALID_SERVER_STATE; 151b3700b07SGordon Ross goto out; 152b3700b07SGordon Ross } 153b3700b07SGordon Ross 154b3700b07SGordon Ross if (args.DomainName != NULL && args.DomainName[0] != '\0' && 155b3700b07SGordon Ross 0 != strcasecmp(args.DomainName, pgcfg->domain_name)) { 156b3700b07SGordon Ross /* 157b3700b07SGordon Ross * They asked for a specific domain not our primary, 158b3700b07SGordon Ross * which is not supported (and not needed). 159b3700b07SGordon Ross */ 160b3700b07SGordon Ross res->status = NT_STATUS_NO_SUCH_DOMAIN; 161b3700b07SGordon Ross goto out; 162b3700b07SGordon Ross } 163b3700b07SGordon Ross 164b3700b07SGordon Ross if ((ds = pgcfg->domain_controller) == NULL) { 165b3700b07SGordon Ross res->status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 166b3700b07SGordon Ross goto out; 167b3700b07SGordon Ross } 168b3700b07SGordon Ross 169b3700b07SGordon Ross dci->dci_DcName = strdup(ds->host); 170b3700b07SGordon Ross 171b3700b07SGordon Ross dci->dci_DcAddr = calloc(1, INET6_ADDRSTRLEN); 172b3700b07SGordon Ross if (dci->dci_DcAddr != NULL && 173b3700b07SGordon Ross ad_disc_getnameinfo(dci->dci_DcAddr, INET6_ADDRSTRLEN, 174b3700b07SGordon Ross &ds->addr) == 0) 175b3700b07SGordon Ross dci->dci_AddrType = DS_INET_ADDRESS; 176b3700b07SGordon Ross 177b3700b07SGordon Ross if ((s = pgcfg->domain_guid) != NULL && 178b3700b07SGordon Ross 0 == uuid_parse(s, uuid)) { 179b3700b07SGordon Ross (void) memcpy(dci->dci_guid, uuid, sizeof (uuid)); 180b3700b07SGordon Ross } 181b3700b07SGordon Ross 182b3700b07SGordon Ross if ((s = pgcfg->domain_name) != NULL) 183b3700b07SGordon Ross dci->dci_DomainName = strdup(s); 184b3700b07SGordon Ross 185b3700b07SGordon Ross if ((s = pgcfg->forest_name) != NULL) 186b3700b07SGordon Ross dci->dci_DnsForestName = strdup(s); 187b3700b07SGordon Ross 188b3700b07SGordon Ross dci->dci_Flags = ds->flags; 189b3700b07SGordon Ross dci->dci_DcSiteName = strdup(ds->site); 190b3700b07SGordon Ross 191b3700b07SGordon Ross if ((s = pgcfg->site_name) != NULL) 192b3700b07SGordon Ross dci->dci_ClientSiteName = strdup(s); 193b3700b07SGordon Ross 194b3700b07SGordon Ross /* Address in binary form too. */ 195b3700b07SGordon Ross (void) memcpy(&dci->dci_sockaddr, 196b3700b07SGordon Ross &ds->addr, ADSPRIV_SOCKADDR_LEN); 197b3700b07SGordon Ross 198b3700b07SGordon Ross out: 199b3700b07SGordon Ross UNLOCK_CONFIG(); 200b3700b07SGordon Ross 201b3700b07SGordon Ross return (TRUE); 202b3700b07SGordon Ross } 203b3700b07SGordon Ross 204b3700b07SGordon Ross /* ARGSUSED */ 205b3700b07SGordon Ross int 206b3700b07SGordon Ross adspriv_program_1_freeresult(SVCXPRT *xprt, xdrproc_t fun, caddr_t res) 207b3700b07SGordon Ross { 208*a17ce845SMarcel Telka xdr_free(fun, res); 209b3700b07SGordon Ross return (TRUE); 210b3700b07SGordon Ross } 211