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