preparing for release of alpha.2.5
[Samba.git] / source / lib / util_hnd.c
blob13f81991f8c147d266a68fe46e319a6e82cfb4e7
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, 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(3, ("Duplicating policy state pnum=%x\n", p->pnum));
226 return register_policy_hnd(cache, &p->key, hnd, p->access_mask);
229 /****************************************************************************
230 find first available policy slot. creates a policy handle for you.
231 ****************************************************************************/
232 BOOL register_policy_hnd(struct policy_cache *cache,
233 const vuser_key * key,
234 POLICY_HND *hnd, uint32 access_mask)
236 struct policy *p;
237 static int count = 1;
239 p = (struct policy *)malloc(sizeof(*p));
240 if (!p)
242 DEBUG(0, ("ERROR: out of memory!\n"));
243 return False;
246 ZERO_STRUCTP(p);
248 p->open = True;
249 p->pnum = count++;
250 p->access_mask = access_mask;
251 if (key != NULL)
253 p->key = *key;
255 else
257 p->key.vuid = UID_FIELD_INVALID;
258 p->key.pid = getpid();
262 DLIST_ADD(cache->Policy, p);
264 DEBUG(4, ("Opened policy hnd[%x] ", p->pnum));
265 DEBUG(10, ("register_policy_hnd: vuser [%d, %x]\n",
266 p->key.pid, p->key.vuid));
268 memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
269 dump_data(4, (char *)hnd, sizeof(*hnd));
271 return True;
274 /****************************************************************************
275 find first available policy slot. creates a policy handle for you.
276 ****************************************************************************/
277 BOOL open_policy_hnd(struct policy_cache *cache,
278 const vuser_key * key,
279 POLICY_HND *hnd, uint32 access_mask)
281 create_pol_hnd(hnd);
282 return register_policy_hnd(cache, key, hnd, access_mask);
285 /****************************************************************************
286 find first available policy slot. creates a policy handle for you.
287 ****************************************************************************/
288 BOOL open_policy_hnd_link(struct policy_cache *cache,
289 const POLICY_HND *parent_hnd,
290 POLICY_HND *hnd, uint32 access_mask)
292 const vuser_key *key = get_policy_vuser_key(cache, parent_hnd);
293 if (key == NULL)
295 return False;
297 create_pol_hnd(hnd);
298 return register_policy_hnd(cache, key, hnd, access_mask);
301 /****************************************************************************
302 find policy index by handle
303 ****************************************************************************/
304 int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd)
306 struct policy *p = find_policy(cache, hnd);
308 return p ? p->pnum : -1;
312 /****************************************************************************
313 set pol state.
314 ****************************************************************************/
315 BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
316 void (*fn) (void *), void *dev)
318 struct policy *p = find_policy(cache, hnd);
320 if (p && p->open)
322 DEBUG(3, ("policy(pnum=%x %s): Setting policy state\n",
323 p->pnum, pol_get_name(p)));
325 p->dev = dev;
326 p->free_fn = fn;
327 return True;
330 DEBUG(3, ("Error setting policy state\n"));
332 return False;
335 /****************************************************************************
336 get pol state.
337 ****************************************************************************/
338 void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd)
340 struct policy *p = find_policy(cache, hnd);
342 if (p != NULL && p->open)
344 DEBUG(3, ("policy(pnum=%x %s): Getting policy state\n",
345 p->pnum, pol_get_name(p)));
346 return p->dev;
349 DEBUG(3, ("Error getting policy state\n"));
350 return NULL;
353 /****************************************************************************
354 set the type of the state of a POLICY_HND
355 ****************************************************************************/
356 BOOL policy_hnd_set_state_type(struct policy_cache *cache,
357 POLICY_HND *hnd, int type)
359 struct policy *p = find_policy(cache, hnd);
361 if (!p || !p->open)
363 DEBUG(3, ("Error setting type for policy state\n"));
364 return False;
366 DEBUG(4, ("policy(pnum=%x %s): setting type to %d\n",
367 p->pnum, pol_get_name(p), type));
368 p->type = type;
369 return True;
372 /****************************************************************************
373 get the type of the state of a POLICY_HND
374 ****************************************************************************/
375 int policy_hnd_get_state_type(struct policy_cache *cache,
376 const POLICY_HND *hnd)
378 struct policy *p = find_policy(cache, hnd);
380 if (!p || !p->open)
382 DEBUG(3, ("Error getting type for policy state\n"));
383 return -1;
385 DEBUG(4, ("policy(pnum=%x %s): getting type %d\n",
386 p->pnum, pol_get_name(p), p->type));
388 return p->type;
391 /****************************************************************************
392 check the type of the state of a POLICY_HND
393 ****************************************************************************/
394 BOOL policy_hnd_check_state_type(struct policy_cache *cache,
395 const POLICY_HND *hnd, int type)
397 struct policy *p = find_policy(cache, hnd);
398 BOOL ret;
400 if (!p || !p->open)
402 DEBUG(3, ("Error checking type for policy state\n"));
403 return False;
406 ret = (p->type == type);
408 if (ret)
410 DEBUG(4, ("policy(pnum=%x %s): checking if type %d is %d\n",
411 p->pnum, pol_get_name(p), p->type, type));
413 else
415 DEBUG(3, ("policy(pnum=%x %s): type %d is not %d\n",
416 p->pnum, pol_get_name(p), p->type, type));
419 return ret;
422 /****************************************************************************
423 close an lsa policy
424 ****************************************************************************/
425 BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd)
427 struct policy *p = find_policy(cache, hnd);
429 if (!p)
431 DEBUG(3, ("Error closing policy\n"));
432 return False;
435 DEBUG(3, ("policy(pnum=%x %s): Closing\n", p->pnum, pol_get_name(p)));
437 DLIST_REMOVE(cache->Policy, p);
439 ZERO_STRUCTP(hnd);
441 if (p->free_fn != NULL)
443 p->free_fn(p->dev);
445 else
447 safe_free(p->dev);
450 safe_free(p->name);
451 free(p);
453 DEBUG(10, ("policy closed\n"));
455 return True;
458 /****************************************************************************
459 get pol state.
460 ****************************************************************************/
461 BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
462 POLICY_HND *to)
464 struct policy *p = find_policy(cache, hnd);
465 struct policy *pto = find_policy(cache, to);
467 if (p != NULL && p->open && pto != NULL && pto->open)
469 DEBUG(3, ("Linking policy key pnum=%x pid=%d vuid=%x\n",
470 p->key.pid, p->key.vuid, p->pnum));
471 pto->key = p->key;
472 return True;
475 DEBUG(3, ("Error getting policy link states\n"));
476 return False;
479 /****************************************************************************
480 get pol state.
481 ****************************************************************************/
482 const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
483 const POLICY_HND *hnd)
485 struct policy *p = find_policy(cache, hnd);
487 if (p != NULL && p->open)
489 DEBUG(3, ("Getting policy vuser_key pnum=%x pid=%d vuid=%x\n",
490 p->pnum, p->key.pid, p->key.vuid));
491 return &p->key;
494 DEBUG(3, ("Error getting policy state\n"));
495 return NULL;
498 /****************************************************************************
499 get user session key.
500 ****************************************************************************/
501 BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
502 uchar usr_sess_key[16])
504 const vuser_key *key = get_policy_vuser_key(cache, hnd);
505 user_struct *vuser;
507 if (key == NULL || key->vuid == UID_FIELD_INVALID)
509 memset(usr_sess_key, 0, 16);
510 return True;
512 vuser = get_valid_user_struct(key);
513 if (vuser == NULL)
515 DEBUG(10, ("pol_get_usr_sesskey: no vuser struct\n"));
516 return False;
518 memcpy(usr_sess_key, vuser->usr.user_sess_key, 16);
519 vuid_free_user_struct(vuser);
520 return True;