preparing for release of alpha-2.6
[Samba/gbeck.git] / source / lib / util_hnd.c
blob2d70d0cdbfae3bc772cd61c3d237bb9b74c52292
2 /*
3 * Unix SMB/Netbios implementation.
4 * Version 1.9.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
8 * Copyright (C) Elrond 2000
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "includes.h"
29 extern int DEBUGLEVEL;
32 struct policy
34 struct policy *next, *prev;
35 int pnum;
36 BOOL open;
37 POLICY_HND pol_hnd;
38 uint32 access_mask;
39 vuser_key key;
41 char *name;
43 int type;
44 void (*free_fn) (void *);
45 void *dev;
48 /****************************************************************************
49 i hate this. a global policy handle cache. yuk.
50 ****************************************************************************/
51 struct policy_cache *get_global_hnd_cache(void)
53 static struct policy_cache *cache = NULL;
55 if (cache == NULL)
57 cache = init_policy_cache(1024);
59 return cache;
62 /****************************************************************************
63 create a unique policy handle
64 ****************************************************************************/
65 static void create_pol_hnd(POLICY_HND *hnd)
67 static uint32 pol_hnd_low = 0;
68 NTTIME ntt;
70 if (hnd == NULL)
71 return;
73 ZERO_STRUCTP(hnd);
75 pol_hnd_low++;
77 unix_to_nt_time(&ntt, time(NULL));
79 hnd->ptr = 0;
80 hnd->uuid.time_low = ntt.low;
81 hnd->uuid.time_mid = (ntt.high & 0xffff);
82 hnd->uuid.time_hi_and_version = ((ntt.high >> 16) & 0xffff);
83 SIVAL(hnd->uuid.remaining, 0, sys_getpid());
84 SIVAL(hnd->uuid.remaining, 4, pol_hnd_low);
87 /****************************************************************************
88 initialise policy handle states...
89 ****************************************************************************/
90 struct policy_cache *init_policy_cache(int num_pol_hnds)
92 struct policy_cache *cache = malloc(sizeof(struct policy_cache));
93 if (cache != NULL)
95 cache->bmap = NULL;
96 cache->Policy = NULL;
98 return cache;
101 /****************************************************************************
102 free policy handle states...
103 ****************************************************************************/
104 void free_policy_cache(struct policy_cache *cache)
106 free(cache);
109 /****************************************************************************
110 find policy by handle
111 ****************************************************************************/
112 static struct policy *find_policy(struct policy_cache *cache,
113 const POLICY_HND *hnd)
115 struct policy *p;
117 if (cache == NULL)
119 DEBUG(0, ("find_policy: NULL cache\n"));
120 SMB_ASSERT(False);
123 if (hnd == NULL)
125 DEBUG(0, ("find_policy: NULL handle\n"));
126 SMB_ASSERT(False);
127 return NULL;
130 for (p = cache->Policy; p; p = p->next)
132 DEBUG(10, ("Compare policy hnd[%x] ", p->pnum));
133 dump_data(10, (const char *)hnd, sizeof(*hnd));
134 if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0)
136 DEBUG(4, ("Found policy hnd[%x] ", p->pnum));
137 dump_data(4, (const char *)hnd, sizeof(*hnd));
138 return p;
142 DEBUG(4, ("cache->Policy not found: "));
143 dump_data(4, (const char *)hnd, sizeof(*hnd));
145 return NULL;
148 /****************************************************************************
149 set the name of a POLICY_HND
150 ****************************************************************************/
151 BOOL policy_hnd_set_name(struct policy_cache *cache,
152 POLICY_HND *hnd, const char *name)
154 struct policy *p = find_policy(cache, hnd);
155 if (!p)
157 DEBUG(3, ("Error setting name for policy\n"));
158 return False;
160 safe_free(p->name);
161 if (name)
163 DEBUG(4, ("policy(pnum=%x): setting name to %s\n",
164 p->pnum, name));
165 p->name = strdup(name);
166 return (p->name != NULL);
168 else
170 DEBUG(4, ("policy(pnum=%x): setting name to %s\n",
171 p->pnum, "NULL"));
172 p->name = NULL;
173 return True;
177 /****************************************************************************
178 get the name of a POLICY_HND
179 ****************************************************************************/
180 static const char *pol_get_name(const struct policy *p)
182 if (!p)
184 return "(NULL)";
186 if (p->name)
188 return p->name;
190 return "";
193 /****************************************************************************
194 get the name of a POLICY_HND, public interface
195 ****************************************************************************/
196 const char *policy_hnd_get_name(struct policy_cache *cache,
197 const POLICY_HND *hnd)
199 const char *name;
200 struct policy *p = find_policy(cache, hnd);
202 if (!p)
204 DEBUG(3, ("Error getting name for policy\n"));
205 return "(invalid POLICY_HND)";
207 name = pol_get_name(p);
208 DEBUG(4, ("policy(pnum=%x %s): getting name\n", p->pnum, name));
209 return name;
213 /****************************************************************************
214 find first available policy slot. copies a policy handle for you.
215 ****************************************************************************/
216 BOOL dup_policy_hnd(struct policy_cache *cache,
217 POLICY_HND *hnd, const POLICY_HND *from)
219 struct policy *p = find_policy(cache, from);
221 if (!p || !p->open)
223 return False;
225 DEBUG(5, ("policy(pnum=%x %s): Duplicating policy\n",
226 p->pnum, pol_get_name(p)));
227 return register_policy_hnd(cache, &p->key, hnd, p->access_mask);
230 /****************************************************************************
231 find first available policy slot. creates a policy handle for you.
232 ****************************************************************************/
233 BOOL register_policy_hnd(struct policy_cache *cache,
234 const vuser_key * key,
235 POLICY_HND *hnd, uint32 access_mask)
237 struct policy *p;
238 static int count = 1;
240 p = (struct policy *)malloc(sizeof(*p));
241 if (!p)
243 DEBUG(0, ("ERROR: out of memory!\n"));
244 return False;
247 ZERO_STRUCTP(p);
249 p->open = True;
250 p->pnum = count++;
251 p->access_mask = access_mask;
252 if (key != NULL)
254 p->key = *key;
256 else
258 p->key.vuid = UID_FIELD_INVALID;
259 p->key.pid = sys_getpid();
263 DLIST_ADD(cache->Policy, p);
265 DEBUG(4, ("Opened policy hnd[%x] ", p->pnum));
266 DEBUG(10, ("register_policy_hnd: vuser [%d, %x]\n",
267 p->key.pid, p->key.vuid));
269 memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
270 dump_data(4, (char *)hnd, sizeof(*hnd));
272 return True;
275 /****************************************************************************
276 find first available policy slot. creates a policy handle for you.
277 ****************************************************************************/
278 BOOL open_policy_hnd(struct policy_cache *cache,
279 const vuser_key * key,
280 POLICY_HND *hnd, uint32 access_mask)
282 create_pol_hnd(hnd);
283 return register_policy_hnd(cache, key, hnd, access_mask);
286 /****************************************************************************
287 find first available policy slot. creates a policy handle for you.
288 ****************************************************************************/
289 BOOL open_policy_hnd_link(struct policy_cache *cache,
290 const POLICY_HND *parent_hnd,
291 POLICY_HND *hnd, uint32 access_mask)
293 const vuser_key *key = get_policy_vuser_key(cache, parent_hnd);
294 if (key == NULL)
296 return False;
298 create_pol_hnd(hnd);
299 return register_policy_hnd(cache, key, hnd, access_mask);
302 /****************************************************************************
303 find policy index by handle
304 ****************************************************************************/
305 int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd)
307 struct policy *p = find_policy(cache, hnd);
309 return p ? p->pnum : -1;
313 /****************************************************************************
314 set pol state.
315 ****************************************************************************/
316 BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
317 void (*fn) (void *), void *dev)
319 struct policy *p = find_policy(cache, hnd);
321 if (p && p->open)
323 DEBUG(5, ("policy(pnum=%x %s): Setting policy state\n",
324 p->pnum, pol_get_name(p)));
326 p->dev = dev;
327 p->free_fn = fn;
328 return True;
331 DEBUG(3, ("Error setting policy state\n"));
333 return False;
336 /****************************************************************************
337 get pol state.
338 ****************************************************************************/
339 void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd)
341 struct policy *p = find_policy(cache, hnd);
343 if (p != NULL && p->open)
345 DEBUG(5, ("policy(pnum=%x %s): Getting policy state\n",
346 p->pnum, pol_get_name(p)));
347 return p->dev;
350 DEBUG(3, ("Error getting policy state\n"));
351 return NULL;
354 /****************************************************************************
355 set the type of the state of a POLICY_HND
356 ****************************************************************************/
357 BOOL policy_hnd_set_state_type(struct policy_cache *cache,
358 POLICY_HND *hnd, int type)
360 struct policy *p = find_policy(cache, hnd);
362 if (!p || !p->open)
364 DEBUG(3, ("Error setting type for policy state\n"));
365 return False;
367 DEBUG(4, ("policy(pnum=%x %s): setting type to %d\n",
368 p->pnum, pol_get_name(p), type));
369 p->type = type;
370 return True;
373 /****************************************************************************
374 get the type of the state of a POLICY_HND
375 ****************************************************************************/
376 int policy_hnd_get_state_type(struct policy_cache *cache,
377 const POLICY_HND *hnd)
379 struct policy *p = find_policy(cache, hnd);
381 if (!p || !p->open)
383 DEBUG(3, ("Error getting type for policy state\n"));
384 return -1;
386 DEBUG(4, ("policy(pnum=%x %s): getting type %d\n",
387 p->pnum, pol_get_name(p), p->type));
389 return p->type;
392 /****************************************************************************
393 check the type of the state of a POLICY_HND
394 ****************************************************************************/
395 BOOL policy_hnd_check_state_type(struct policy_cache *cache,
396 const POLICY_HND *hnd, int type)
398 struct policy *p = find_policy(cache, hnd);
399 BOOL ret;
401 if (!p || !p->open)
403 DEBUG(3, ("Error checking type for policy state\n"));
404 return False;
407 ret = (p->type == type);
409 if (ret)
411 DEBUG(4, ("policy(pnum=%x %s): checking if type %d is %d\n",
412 p->pnum, pol_get_name(p), p->type, type));
414 else
416 DEBUG(3, ("policy(pnum=%x %s): type %d is not %d\n",
417 p->pnum, pol_get_name(p), p->type, type));
420 return ret;
423 /****************************************************************************
424 close an lsa policy
425 ****************************************************************************/
426 BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd)
428 struct policy *p = find_policy(cache, hnd);
430 if (!p)
432 DEBUG(3, ("Error closing policy\n"));
433 return False;
436 DEBUG(5, ("policy(pnum=%x %s): Closing\n", p->pnum, pol_get_name(p)));
438 DLIST_REMOVE(cache->Policy, p);
440 ZERO_STRUCTP(hnd);
442 if (p->free_fn != NULL)
444 p->free_fn(p->dev);
446 else
448 safe_free(p->dev);
451 safe_free(p->name);
452 free(p);
454 DEBUG(10, ("policy closed\n"));
456 return True;
459 /****************************************************************************
460 get pol state.
461 ****************************************************************************/
462 BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
463 POLICY_HND *to)
465 struct policy *p = find_policy(cache, hnd);
466 struct policy *pto = find_policy(cache, to);
468 if (p != NULL && p->open && pto != NULL && pto->open)
470 DEBUG(3, ("Linking policy key pnum=%x pid=%d vuid=%x\n",
471 p->key.pid, p->key.vuid, p->pnum));
472 pto->key = p->key;
473 return True;
476 DEBUG(3, ("Error getting policy link states\n"));
477 return False;
480 /****************************************************************************
481 get pol state.
482 ****************************************************************************/
483 const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
484 const POLICY_HND *hnd)
486 struct policy *p = find_policy(cache, hnd);
488 if (p != NULL && p->open)
490 DEBUG(5, ("Getting policy vuser_key pnum=%x pid=%d vuid=%x\n",
491 p->pnum, p->key.pid, p->key.vuid));
492 return &p->key;
495 DEBUG(3, ("Error getting policy state\n"));
496 return NULL;
499 /****************************************************************************
500 get user session key.
501 ****************************************************************************/
502 BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
503 uchar usr_sess_key[16])
505 const vuser_key *key = get_policy_vuser_key(cache, hnd);
506 user_struct *vuser;
508 if (key == NULL || key->vuid == UID_FIELD_INVALID)
510 memset(usr_sess_key, 0, 16);
511 return True;
513 vuser = get_valid_user_struct(key);
514 if (vuser == NULL)
516 DEBUG(10, ("pol_get_usr_sesskey: no vuser struct\n"));
517 return False;
519 memcpy(usr_sess_key, vuser->usr.user_sess_key, 16);
520 vuid_free_user_struct(vuser);
521 return True;