1*4520Snw141292 /*
2*4520Snw141292  * CDDL HEADER START
3*4520Snw141292  *
4*4520Snw141292  * The contents of this file are subject to the terms of the
5*4520Snw141292  * Common Development and Distribution License (the "License").
6*4520Snw141292  * You may not use this file except in compliance with the License.
7*4520Snw141292  *
8*4520Snw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4520Snw141292  * or http://www.opensolaris.org/os/licensing.
10*4520Snw141292  * See the License for the specific language governing permissions
11*4520Snw141292  * and limitations under the License.
12*4520Snw141292  *
13*4520Snw141292  * When distributing Covered Code, include this CDDL HEADER in each
14*4520Snw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4520Snw141292  * If applicable, add the following below this CDDL HEADER, with the
16*4520Snw141292  * fields enclosed by brackets "[]" replaced with your own identifying
17*4520Snw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4520Snw141292  *
19*4520Snw141292  * CDDL HEADER END
20*4520Snw141292  */
21*4520Snw141292 
22*4520Snw141292 /*
23*4520Snw141292  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*4520Snw141292  * Use is subject to license terms.
25*4520Snw141292  */
26*4520Snw141292 
27*4520Snw141292 #ifndef _ADUTILS_H
28*4520Snw141292 #define	_ADUTILS_H
29*4520Snw141292 
30*4520Snw141292 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*4520Snw141292 
32*4520Snw141292 #ifdef __cplusplus
33*4520Snw141292 extern "C" {
34*4520Snw141292 #endif
35*4520Snw141292 
36*4520Snw141292 /*
37*4520Snw141292  * Processes name2sid & sid2name lookups for a given user or computer
38*4520Snw141292  * from an AD Difrectory server using GSSAPI authentication
39*4520Snw141292  */
40*4520Snw141292 
41*4520Snw141292 #include <stdio.h>
42*4520Snw141292 #include <stdlib.h>
43*4520Snw141292 #include <unistd.h>
44*4520Snw141292 #include <lber.h>
45*4520Snw141292 #include <ldap.h>
46*4520Snw141292 #include <sasl/sasl.h>
47*4520Snw141292 #include <string.h>
48*4520Snw141292 #include <ctype.h>
49*4520Snw141292 #include <sys/types.h>
50*4520Snw141292 #include <time.h>
51*4520Snw141292 #include <thread.h>
52*4520Snw141292 #include <synch.h>
53*4520Snw141292 #include "idmap_prot.h"
54*4520Snw141292 #include <sys/idmap.h>
55*4520Snw141292 
56*4520Snw141292 /*
57*4520Snw141292  * idmapd interfaces stolen? from other idmapd code?
58*4520Snw141292  */
59*4520Snw141292 
60*4520Snw141292 /*
61*4520Snw141292  * Eventually these should be an enum here, but instead we share a
62*4520Snw141292  * namespace with other things in idmapd.
63*4520Snw141292  */
64*4520Snw141292 #define	_IDMAP_T_OTHER		0
65*4520Snw141292 #define	_IDMAP_T_USER		-1004
66*4520Snw141292 #define	_IDMAP_T_GROUP		-1005
67*4520Snw141292 #define	_IDMAP_T_DOMAIN		-1006
68*4520Snw141292 #define	_IDMAP_T_COMPUTER	-1007
69*4520Snw141292 
70*4520Snw141292 #define	SID_MAX_SUB_AUTHORITIES	15
71*4520Snw141292 #define	MAXBINSID	(1 + 1 + 6 + (SID_MAX_SUB_AUTHORITIES * 4))
72*4520Snw141292 #define	MAXHEXBINSID	(MAXBINSID * 3)
73*4520Snw141292 
74*4520Snw141292 typedef uint32_t rid_t;
75*4520Snw141292 
76*4520Snw141292 /*
77*4520Snw141292  * We use the port numbers for normal LDAP and global catalog LDAP as
78*4520Snw141292  * the enum values for this enumeration.  Clever?  Silly?  You decide.
79*4520Snw141292  * Although we never actually use these enum values as port numbers and
80*4520Snw141292  * never will, so this is just cute.
81*4520Snw141292  */
82*4520Snw141292 typedef enum idmap_ad_partition {
83*4520Snw141292 	IDMAP_AD_DATA = 389,
84*4520Snw141292 	IDMAP_AD_GLOBAL_CATALOG = 3268
85*4520Snw141292 } idmap_ad_partition_t;
86*4520Snw141292 
87*4520Snw141292 typedef struct ad ad_t;
88*4520Snw141292 typedef struct idmap_query_state idmap_query_state_t;
89*4520Snw141292 
90*4520Snw141292 /*
91*4520Snw141292  * Idmap interfaces:
92*4520Snw141292  *
93*4520Snw141292  *  - an ad_t represents an AD partition
94*4520Snw141292  *  - a DS (hostname + port, if port != 0) can be added/removed from an ad_t
95*4520Snw141292  *  - and because libldap supports space-separated lists of servers, a
96*4520Snw141292  *  single hostname value can actually be a set of hostnames.
97*4520Snw141292  *  - an ad_t can be allocated, ref'ed and released; last release
98*4520Snw141292  *  releases resources
99*4520Snw141292  *
100*4520Snw141292  *  - lookups are batched; see below.
101*4520Snw141292  *
102*4520Snw141292  * See below.
103*4520Snw141292  */
104*4520Snw141292 
105*4520Snw141292 /* Allocate/release ad_t objects */
106*4520Snw141292 int idmap_ad_alloc(ad_t **new_ad, const char *default_domain,
107*4520Snw141292 		idmap_ad_partition_t part);
108*4520Snw141292 void idmap_ad_free(ad_t **ad);
109*4520Snw141292 
110*4520Snw141292 /* Add/remove a DS to/from an ad_t */
111*4520Snw141292 int idmap_add_ds(ad_t *ad, const char *host, int port);
112*4520Snw141292 void idmap_delete_ds(ad_t *ad, const char *host, int port);
113*4520Snw141292 
114*4520Snw141292 /*
115*4520Snw141292  * Batch lookups
116*4520Snw141292  *
117*4520Snw141292  * Start a batch, add queries to the batch one by one (the output
118*4520Snw141292  * pointers should all differ, so that a query's results don't clobber
119*4520Snw141292  * any other's), end the batch to wait for replies for all outstanding
120*4520Snw141292  * queries.  The output parameters of each query are initialized to NULL
121*4520Snw141292  * or -1 as appropriate.
122*4520Snw141292  *
123*4520Snw141292  * LDAP searches are sent one by one without waiting (i.e., blocking)
124*4520Snw141292  * for replies.  Replies are handled as soon as they are available.
125*4520Snw141292  * Missing replies are waited for only when idmap_lookup_batch_end() is
126*4520Snw141292  * called.
127*4520Snw141292  *
128*4520Snw141292  * If an add1 function returns != 0 then abort the batch by calling
129*4520Snw141292  * idmap_lookup_batch_end(), but note that some queries may have been
130*4520Snw141292  * answered, so check the result code of each query.
131*4520Snw141292  */
132*4520Snw141292 
133*4520Snw141292 /* Start a batch of lookups */
134*4520Snw141292 idmap_retcode idmap_lookup_batch_start(ad_t *ad, int nqueries,
135*4520Snw141292 		idmap_query_state_t **state);
136*4520Snw141292 
137*4520Snw141292 /* End a batch and release its idmap_query_state_t object */
138*4520Snw141292 idmap_retcode idmap_lookup_batch_end(idmap_query_state_t **state,
139*4520Snw141292 		struct timeval *timeout);
140*4520Snw141292 
141*4520Snw141292 /* Abandon a batch and release its idmap_query_state_t object */
142*4520Snw141292 void idmap_lookup_free_batch(idmap_query_state_t **state);
143*4520Snw141292 
144*4520Snw141292 /*
145*4520Snw141292  * Add a name->SID lookup
146*4520Snw141292  *
147*4520Snw141292  *  - 'dname' is optional; if NULL or empty string then 'name' has to be
148*4520Snw141292  *  a user/group name qualified wih a domainname (e.g., foo@domain),
149*4520Snw141292  *  else the 'name' must not be qualified and the domainname must be
150*4520Snw141292  *  passed in 'dname'.
151*4520Snw141292  *
152*4520Snw141292  *  - if 'rid' is NULL then the output SID string will include the last
153*4520Snw141292  *  RID, else it won't and the last RID value will be stored in *rid.
154*4520Snw141292  *
155*4520Snw141292  *  The caller must free() *sid.
156*4520Snw141292  */
157*4520Snw141292 idmap_retcode idmap_name2sid_batch_add1(idmap_query_state_t *state,
158*4520Snw141292 		const char *name, const char *dname,
159*4520Snw141292 		char **sid, rid_t *rid, int *sid_type, idmap_retcode *rc);
160*4520Snw141292 /*
161*4520Snw141292  * Add a SID->name lookup
162*4520Snw141292  *
163*4520Snw141292  *  - 'rid' is optional; if NULL then 'sid' is expected to have the
164*4520Snw141292  *  user/group RID present, else 'sid' is expected not to have it, and
165*4520Snw141292  *  *rid will be used to qualify the given 'sid'
166*4520Snw141292  *
167*4520Snw141292  *  - 'dname' is optional; if NULL then the fully qualified user/group
168*4520Snw141292  *  name will be stored in *name, else the domain name will be stored in
169*4520Snw141292  *  *dname and the user/group name will be stored in *name without a
170*4520Snw141292  *  domain qualifier.
171*4520Snw141292  *
172*4520Snw141292  *  The caller must free() *name and *dname (if present).
173*4520Snw141292  */
174*4520Snw141292 idmap_retcode idmap_sid2name_batch_add1(idmap_query_state_t *state,
175*4520Snw141292 		const char *sid, const rid_t *rid,
176*4520Snw141292 		char **name, char **dname, int *sid_type, idmap_retcode *rc);
177*4520Snw141292 
178*4520Snw141292 #ifdef __cplusplus
179*4520Snw141292 }
180*4520Snw141292 #endif
181*4520Snw141292 
182*4520Snw141292 #endif	/* _ADUTILS_H */
183