xref: /titanic_51/usr/src/lib/libads/common/dsgetdc.c (revision b3700b074e637f8c6991b70754c88a2cfffb246b)
1*b3700b07SGordon Ross /*
2*b3700b07SGordon Ross  * This file and its contents are supplied under the terms of the
3*b3700b07SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4*b3700b07SGordon Ross  * You may only use this file in accordance with the terms of version
5*b3700b07SGordon Ross  * 1.0 of the CDDL.
6*b3700b07SGordon Ross  *
7*b3700b07SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8*b3700b07SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9*b3700b07SGordon Ross  * http://www.illumos.org/license/CDDL.
10*b3700b07SGordon Ross  */
11*b3700b07SGordon Ross 
12*b3700b07SGordon Ross /*
13*b3700b07SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
14*b3700b07SGordon Ross  */
15*b3700b07SGordon Ross 
16*b3700b07SGordon Ross /*
17*b3700b07SGordon Ross  * MS-compatible Directory Server Discovery API, DsGetDC...()
18*b3700b07SGordon Ross  */
19*b3700b07SGordon Ross 
20*b3700b07SGordon Ross #include <stdlib.h>
21*b3700b07SGordon Ross #include <string.h>
22*b3700b07SGordon Ross #include <smb/nterror.h>
23*b3700b07SGordon Ross #include <smb/ntstatus.h>
24*b3700b07SGordon Ross #include <arpa/inet.h>
25*b3700b07SGordon Ross #include "dsgetdc.h"
26*b3700b07SGordon Ross #include "ads_priv.h"
27*b3700b07SGordon Ross #include <assert.h>
28*b3700b07SGordon Ross 
29*b3700b07SGordon Ross #define	DSGETDC_VALID_FLAGS ( \
30*b3700b07SGordon Ross 	DS_FORCE_REDISCOVERY | \
31*b3700b07SGordon Ross 	DS_DIRECTORY_SERVICE_REQUIRED | \
32*b3700b07SGordon Ross 	DS_DIRECTORY_SERVICE_PREFERRED | \
33*b3700b07SGordon Ross 	DS_GC_SERVER_REQUIRED | \
34*b3700b07SGordon Ross 	DS_PDC_REQUIRED | \
35*b3700b07SGordon Ross 	DS_BACKGROUND_ONLY | \
36*b3700b07SGordon Ross 	DS_IP_REQUIRED | \
37*b3700b07SGordon Ross 	DS_KDC_REQUIRED | \
38*b3700b07SGordon Ross 	DS_TIMESERV_REQUIRED | \
39*b3700b07SGordon Ross 	DS_WRITABLE_REQUIRED | \
40*b3700b07SGordon Ross 	DS_GOOD_TIMESERV_PREFERRED | \
41*b3700b07SGordon Ross 	DS_AVOID_SELF | \
42*b3700b07SGordon Ross 	DS_ONLY_LDAP_NEEDED | \
43*b3700b07SGordon Ross 	DS_IS_FLAT_NAME | \
44*b3700b07SGordon Ross 	DS_IS_DNS_NAME | \
45*b3700b07SGordon Ross 	DS_RETURN_FLAT_NAME | \
46*b3700b07SGordon Ross 	DS_RETURN_DNS_NAME)
47*b3700b07SGordon Ross 
48*b3700b07SGordon Ross static struct timeval TIMEOUT = { 15, 0 };
49*b3700b07SGordon Ross 
50*b3700b07SGordon Ross /*
51*b3700b07SGordon Ross  * The Windows version of this would return a single allocation,
52*b3700b07SGordon Ross  * where any strings pointed to in the returned structure would be
53*b3700b07SGordon Ross  * stored in space following the top-level returned structure.
54*b3700b07SGordon Ross  * This allows NetApiBufferFree() to be the same as free().
55*b3700b07SGordon Ross  *
56*b3700b07SGordon Ross  * However, we don't have an easy way to do that right now, so
57*b3700b07SGordon Ross  * the dcinfo returned here will be free'd with DsFreeDcInfo().
58*b3700b07SGordon Ross  */
59*b3700b07SGordon Ross uint32_t
60*b3700b07SGordon Ross _DsGetDcName(const char *ComputerName,
61*b3700b07SGordon Ross     const char *DomainName, const struct uuid *DomainGuid,
62*b3700b07SGordon Ross     const char *SiteName, uint32_t Flags,
63*b3700b07SGordon Ross     DOMAIN_CONTROLLER_INFO **dcinfo)
64*b3700b07SGordon Ross {
65*b3700b07SGordon Ross 	DsGetDcNameArgs args;
66*b3700b07SGordon Ross 	DsGetDcNameRes res;
67*b3700b07SGordon Ross 	CLIENT *clnt = NULL;
68*b3700b07SGordon Ross 	enum clnt_stat clstat;
69*b3700b07SGordon Ross 
70*b3700b07SGordon Ross 	*dcinfo = NULL;
71*b3700b07SGordon Ross 	(void) memset(&args, 0, sizeof (args));
72*b3700b07SGordon Ross 	(void) memset(&res, 0, sizeof (res));
73*b3700b07SGordon Ross 
74*b3700b07SGordon Ross 	/*
75*b3700b07SGordon Ross 	 * Later check for over constrained optional args here,
76*b3700b07SGordon Ross 	 * and return (ERROR_INVALID_PARAMETER);
77*b3700b07SGordon Ross 	 */
78*b3700b07SGordon Ross 
79*b3700b07SGordon Ross 	if (Flags & ~DSGETDC_VALID_FLAGS)
80*b3700b07SGordon Ross 		return (ERROR_INVALID_FLAGS);
81*b3700b07SGordon Ross 
82*b3700b07SGordon Ross 	/*
83*b3700b07SGordon Ross 	 * Call the ADS deamon.
84*b3700b07SGordon Ross 	 */
85*b3700b07SGordon Ross 	clnt = clnt_door_create(ADSPRIV_PROGRAM, ADSPRIV_V1, ADSPRIV_MAX_XFER);
86*b3700b07SGordon Ross 	if (clnt == NULL)
87*b3700b07SGordon Ross 		return (RPC_S_NOT_LISTENING);
88*b3700b07SGordon Ross 
89*b3700b07SGordon Ross 	args.ComputerName = (char *)ComputerName;
90*b3700b07SGordon Ross 	args.DomainName = (char *)DomainName;
91*b3700b07SGordon Ross 	if (DomainGuid != NULL)
92*b3700b07SGordon Ross 		(void) memcpy(&args.DomainGuid, DomainGuid,
93*b3700b07SGordon Ross 		    sizeof (args.DomainGuid));
94*b3700b07SGordon Ross 	args.SiteName = (char *)SiteName;
95*b3700b07SGordon Ross 	args.Flags = Flags;
96*b3700b07SGordon Ross 
97*b3700b07SGordon Ross 	clstat = clnt_call(clnt, ADSPRIV_GetDcName,
98*b3700b07SGordon Ross 	    (xdrproc_t)xdr_DsGetDcNameArgs, (caddr_t)&args,
99*b3700b07SGordon Ross 	    (xdrproc_t)xdr_DsGetDcNameRes, (caddr_t)&res, TIMEOUT);
100*b3700b07SGordon Ross 
101*b3700b07SGordon Ross 	clnt_destroy(clnt);
102*b3700b07SGordon Ross 	if (clstat != RPC_SUCCESS)
103*b3700b07SGordon Ross 		return (RPC_S_CALL_FAILED);
104*b3700b07SGordon Ross 	if (res.status != 0)
105*b3700b07SGordon Ross 		return (res.status);
106*b3700b07SGordon Ross 
107*b3700b07SGordon Ross 	*dcinfo = malloc(sizeof (**dcinfo));
108*b3700b07SGordon Ross 	if (*dcinfo == NULL)
109*b3700b07SGordon Ross 		return (ERROR_NOT_ENOUGH_MEMORY);
110*b3700b07SGordon Ross 
111*b3700b07SGordon Ross 	/*
112*b3700b07SGordon Ross 	 * We have taken pains to make these two the same.
113*b3700b07SGordon Ross 	 * DOMAIN_CONTROLLER_INFO / struct adspriv_dcinfo
114*b3700b07SGordon Ross 	 */
115*b3700b07SGordon Ross 	/* LINTED E_TRUE_LOGICAL_EXPR */
116*b3700b07SGordon Ross 	assert(sizeof (**dcinfo) == sizeof (res.DsGetDcNameRes_u.res0));
117*b3700b07SGordon Ross 	(void) memcpy(*dcinfo, &res.DsGetDcNameRes_u.res0, sizeof (**dcinfo));
118*b3700b07SGordon Ross 
119*b3700b07SGordon Ross 	/*
120*b3700b07SGordon Ross 	 * NB: Do NOT xdr_free the result, because we're
121*b3700b07SGordon Ross 	 * returning a copy of it to the caller.
122*b3700b07SGordon Ross 	 */
123*b3700b07SGordon Ross 	return (0);
124*b3700b07SGordon Ross }
125*b3700b07SGordon Ross 
126*b3700b07SGordon Ross int
127*b3700b07SGordon Ross DsGetDcName(const char *ComputerName,
128*b3700b07SGordon Ross     const char *DomainName, const struct uuid *DomainGuid,
129*b3700b07SGordon Ross     const char *SiteName, uint32_t Flags,
130*b3700b07SGordon Ross     DOMAIN_CONTROLLER_INFO **dcinfo)
131*b3700b07SGordon Ross {
132*b3700b07SGordon Ross 	uint32_t status;
133*b3700b07SGordon Ross 	int rc;
134*b3700b07SGordon Ross 
135*b3700b07SGordon Ross 	status = _DsGetDcName(ComputerName, DomainName, DomainGuid,
136*b3700b07SGordon Ross 	    SiteName, Flags, dcinfo);
137*b3700b07SGordon Ross 
138*b3700b07SGordon Ross 	switch (status) {
139*b3700b07SGordon Ross 	case 0:
140*b3700b07SGordon Ross 		rc = 0;
141*b3700b07SGordon Ross 		break;
142*b3700b07SGordon Ross 	case NT_STATUS_NO_SUCH_DOMAIN:	/* Specified domain unknown */
143*b3700b07SGordon Ross 	case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
144*b3700b07SGordon Ross 	case NT_STATUS_CANT_WAIT:		/* or gave up waiting. */
145*b3700b07SGordon Ross 	case NT_STATUS_INVALID_SERVER_STATE:	/*  not in domain mode. */
146*b3700b07SGordon Ross 		rc = ERROR_NO_SUCH_DOMAIN;
147*b3700b07SGordon Ross 		break;
148*b3700b07SGordon Ross 	default:
149*b3700b07SGordon Ross 		rc = ERROR_INTERNAL_ERROR;
150*b3700b07SGordon Ross 		break;
151*b3700b07SGordon Ross 	}
152*b3700b07SGordon Ross 	return (rc);
153*b3700b07SGordon Ross }
154*b3700b07SGordon Ross 
155*b3700b07SGordon Ross void
156*b3700b07SGordon Ross DsFreeDcInfo(DOMAIN_CONTROLLER_INFO *dci)
157*b3700b07SGordon Ross {
158*b3700b07SGordon Ross 	if (dci != NULL) {
159*b3700b07SGordon Ross 		xdr_free(xdr_DsGetDcNameRes, (char *)dci);
160*b3700b07SGordon Ross 		free(dci);
161*b3700b07SGordon Ross 	}
162*b3700b07SGordon Ross }
163