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