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
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.
24 #include <smb/ntstatus.h>
27 #include <arpa/inet.h>
28 #include <uuid/uuid.h>
31 #include "libadutils.h"
35 void adspriv_program_1(struct svc_req
*, register SVCXPRT
*);
37 SVCXPRT
*dcl_xprt
= NULL
;
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");
51 if (!svc_control(dcl_xprt
, SVCSET_CONNMAXREC
, &connmaxrec
)) {
52 syslog(LOG_ERR
, "unable to limit RPC request size");
60 svc_destroy(dcl_xprt
);
64 * Functions called by the (generated) adspriv_srv.c
69 adspriv_null_1_svc(void *result
, struct svc_req
*rqstp
)
76 adspriv_forcerediscovery_1_svc(
77 DsForceRediscoveryArgs args
,
81 /* Ignoring args for now. */
83 idmap_cfg_force_rediscovery();
92 adspriv_getdcname_1_svc(
99 idmap_pg_config_t
*pgcfg
;
104 (void) memset(res
, 0, sizeof (*res
));
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 };
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) {
128 rc
= cond_reltimedwait(&_idmapdstate
.addisc_cv
,
129 &_idmapdstate
.addisc_lk
, &tv
);
133 (void) mutex_unlock(&_idmapdstate
.addisc_lk
);
136 /* Caller will replace this with DC not found. */
137 idmapdlog(LOG_ERR
, "getdcname timeout");
138 res
->status
= NT_STATUS_CANT_WAIT
;
142 idmapdlog(LOG_DEBUG
, "getdcname wait done");
147 pgcfg
= &_idmapdstate
.cfg
->pgcfg
;
149 if (pgcfg
->domain_name
== NULL
) {
150 res
->status
= NT_STATUS_INVALID_SERVER_STATE
;
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
;
164 if ((ds
= pgcfg
->domain_controller
) == NULL
) {
165 res
->status
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
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
,
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
);
206 adspriv_program_1_freeresult(SVCXPRT
*xprt
, xdrproc_t fun
, caddr_t res
)