first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba.git] / source / lib / util_hnd.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26
27
28 extern int DEBUGLEVEL;
29
30 #ifndef MAX_OPEN_POLS
31 #define MAX_OPEN_POLS 64
32 #endif
33
34 #define POL_NO_INFO 0
35 #define POL_REG_INFO 1
36 #define POL_SAMR_INFO 2
37 #define POL_CLI_INFO 3
38
39 struct reg_info
40 {
41     /* for use by \PIPE\winreg */
42         fstring name; /* name of registry key */
43 };
44
45 struct samr_info
46 {
47     /* for use by the \PIPE\samr policy */
48         DOM_SID sid;
49     uint32 rid; /* relative id associated with the pol_hnd */
50     uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
51 };
52
53 struct con_info
54 {
55         struct cli_connection *con;
56         void (*free)(struct cli_connection*);
57 };
58
59 static struct policy
60 {
61         struct policy *next, *prev;
62         int pnum;
63         BOOL open;
64         POLICY_HND pol_hnd;
65         int type;
66
67         union {
68                 struct samr_info *samr;
69                 struct reg_info *reg;
70                 struct con_info *con;
71
72         } dev;
73
74 } *Policy;
75
76 static struct bitmap *bmap;
77
78
79 /****************************************************************************
80   create a unique policy handle
81 ****************************************************************************/
82 static void create_pol_hnd(POLICY_HND *hnd)
83 {
84         static uint32 pol_hnd_low  = 0;
85         static uint32 pol_hnd_high = 0;
86
87         if (hnd == NULL) return;
88
89         /* i severely doubt that pol_hnd_high will ever be non-zero... */
90         pol_hnd_low++;
91         if (pol_hnd_low == 0) pol_hnd_high++;
92
93         SIVAL(hnd->data, 0 , 0x0);  /* first bit must be null */
94         SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
95         SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
96         SIVAL(hnd->data, 12, time(NULL)); /* something random */
97         SIVAL(hnd->data, 16, getpid()); /* something more random */
98 }
99
100 /****************************************************************************
101   initialise policy handle states...
102 ****************************************************************************/
103 BOOL init_policy_hnd(int num_pol_hnds)
104 {
105         bmap = bitmap_allocate(num_pol_hnds);
106         
107         return bmap != NULL;
108 }
109
110 /****************************************************************************
111   find first available policy slot.  creates a policy handle for you.
112 ****************************************************************************/
113 BOOL register_policy_hnd(POLICY_HND *hnd)
114 {
115         int i;
116         struct policy *p;
117
118         i = bitmap_find(bmap, 1);
119
120         if (i == -1) {
121                 DEBUG(0,("ERROR: out of Policy Handles!\n"));
122                 return False;
123         }
124
125         p = (struct policy *)malloc(sizeof(*p));
126         if (!p) {
127                 DEBUG(0,("ERROR: out of memory!\n"));
128                 return False;
129         }
130
131         ZERO_STRUCTP(p);
132
133         p->open = True;                         
134         p->pnum = i;
135         p->type = POL_NO_INFO;
136
137         memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
138
139         bitmap_set(bmap, i);
140
141         DLIST_ADD(Policy, p);
142         
143         DEBUG(4,("Opened policy hnd[%x] ", i));
144         dump_data(4, (char *)hnd->data, sizeof(hnd->data));
145
146         return True;
147 }
148
149 /****************************************************************************
150   find first available policy slot.  creates a policy handle for you.
151 ****************************************************************************/
152 BOOL open_policy_hnd(POLICY_HND *hnd)
153 {
154         create_pol_hnd(hnd);
155         return register_policy_hnd(hnd);
156 }
157
158 /****************************************************************************
159   find policy by handle
160 ****************************************************************************/
161 static struct policy *find_policy(const POLICY_HND *hnd)
162 {
163         struct policy *p;
164
165         for (p=Policy;p;p=p->next) {
166                 if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
167                         DEBUG(4,("Found policy hnd[%x] ", p->pnum));
168                         dump_data(4, (const char *)hnd->data,
169                         sizeof(hnd->data));
170                         return p;
171                 }
172         }
173
174         DEBUG(4,("Policy not found: "));
175         dump_data(4, (const char *)hnd->data, sizeof(hnd->data));
176
177         return NULL;
178 }
179
180 /****************************************************************************
181   find policy index by handle
182 ****************************************************************************/
183 int find_policy_by_hnd(const POLICY_HND *hnd)
184 {
185         struct policy *p = find_policy(hnd);
186
187         return p?p->pnum:-1;
188 }
189
190 /****************************************************************************
191   set samr rid
192 ****************************************************************************/
193 BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
194 {
195         struct policy *p = find_policy(hnd);
196
197         if (p && p->open)
198         {
199                 DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
200                          rid, p->pnum));
201
202                 if (p->dev.samr == NULL)
203                 {
204                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
205                 }
206                 if (p->dev.samr == NULL)
207                 {
208                         return False;
209                 }
210                 p->dev.samr->rid = rid;
211                 return True;
212         }
213
214         DEBUG(3,("Error setting policy rid=%x\n",rid));
215         return False;
216 }
217
218
219 /****************************************************************************
220   set samr pol status.  absolutely no idea what this is.
221 ****************************************************************************/
222 BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
223 {
224         struct policy *p = find_policy(hnd);
225
226         if (p && p->open)
227         {
228                 DEBUG(3,("Setting policy status=%x pnum=%x\n",
229                           pol_status, p->pnum));
230
231                 if (p->dev.samr == NULL)
232                 {
233                         p->type = POL_SAMR_INFO;
234                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
235                 }
236                 if (p->dev.samr == NULL)
237                 {
238                         return False;
239                 }
240                 p->dev.samr->status = pol_status;
241                 return True;
242         } 
243
244         DEBUG(3,("Error setting policy status=%x\n",
245                  pol_status));
246         return False;
247 }
248
249 /****************************************************************************
250   set samr sid
251 ****************************************************************************/
252 BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
253 {
254         pstring sidstr;
255         struct policy *p = find_policy(hnd);
256
257         if (p && p->open) {
258                 DEBUG(3,("Setting policy sid=%s pnum=%x\n",
259                          sid_to_string(sidstr, sid), p->pnum));
260
261                 if (p->dev.samr == NULL)
262                 {
263                         p->type = POL_SAMR_INFO;
264                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
265                 }
266                 if (p->dev.samr == NULL)
267                 {
268                         return False;
269                 }
270                 memcpy(&p->dev.samr->sid, sid, sizeof(*sid));
271                 return True;
272         }
273
274         DEBUG(3,("Error setting policy sid=%s\n",
275                   sid_to_string(sidstr, sid)));
276         return False;
277 }
278
279 /****************************************************************************
280   get samr sid
281 ****************************************************************************/
282 BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
283 {
284         struct policy *p = find_policy(hnd);
285
286         if (p != NULL && p->open)
287         {
288                 pstring sidstr;
289                 memcpy(sid, &p->dev.samr->sid, sizeof(*sid));
290                 DEBUG(3,("Getting policy sid=%s pnum=%x\n",
291                          sid_to_string(sidstr, sid), p->pnum));
292
293                 return True;
294         }
295
296         DEBUG(3,("Error getting policy\n"));
297         return False;
298 }
299
300 /****************************************************************************
301   get samr rid
302 ****************************************************************************/
303 uint32 get_policy_samr_rid(POLICY_HND *hnd)
304 {
305         struct policy *p = find_policy(hnd);
306
307         if (p && p->open) {
308                 uint32 rid = p->dev.samr->rid;
309                 DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
310                           rid, p->pnum));
311
312                 return rid;
313         }
314
315         DEBUG(3,("Error getting policy\n"));
316         return 0xffffffff;
317 }
318
319 /****************************************************************************
320   set reg name 
321 ****************************************************************************/
322 BOOL set_policy_reg_name(POLICY_HND *hnd, fstring name)
323 {
324         struct policy *p = find_policy(hnd);
325
326         if (p && p->open)
327         {
328                 DEBUG(3,("Getting policy pnum=%x\n",
329                          p->pnum));
330
331                 if (p->dev.reg == NULL)
332                 {
333                         p->type = POL_REG_INFO;
334                         p->dev.reg = (struct reg_info*)malloc(sizeof(*p->dev.reg));
335                 }
336                 if (p->dev.reg == NULL)
337                 {
338                         return False;
339                 }
340                 fstrcpy(p->dev.reg->name, name);
341                 return True;
342         }
343
344         DEBUG(3,("Error setting policy name=%s\n", name));
345         return False;
346 }
347
348 /****************************************************************************
349   set reg name 
350 ****************************************************************************/
351 BOOL get_policy_reg_name(POLICY_HND *hnd, fstring name)
352 {
353         struct policy *p = find_policy(hnd);
354
355         if (p && p->open)
356         {
357                 DEBUG(3,("Setting policy pnum=%x name=%s\n",
358                          p->pnum, name));
359
360                 fstrcpy(name, p->dev.reg->name);
361                 DEBUG(5,("getting policy reg name=%s\n", name));
362                 return True;
363         }
364
365         DEBUG(3,("Error getting policy reg name\n"));
366         return False;
367 }
368
369 /****************************************************************************
370   set con state
371 ****************************************************************************/
372 BOOL set_policy_con(POLICY_HND *hnd, struct cli_connection *con,
373                                 void (*free_fn)(struct cli_connection *))
374 {
375         struct policy *p = find_policy(hnd);
376
377         if (p && p->open)
378         {
379                 DEBUG(3,("Setting policy con state pnum=%x\n", p->pnum));
380
381                 if (p->dev.con == NULL)
382                 {
383                         p->type = POL_CLI_INFO;
384                         p->dev.con = (struct con_info*)malloc(sizeof(*p->dev.con));
385                 }
386                 if (p->dev.con == NULL)
387                 {
388                         return False;
389                 }
390                 p->dev.con->con  = con;
391                 p->dev.con->free = free_fn;
392                 return True;
393         }
394
395         DEBUG(3,("Error setting policy con state\n"));
396
397         return False;
398 }
399
400 /****************************************************************************
401   get con state
402 ****************************************************************************/
403 BOOL get_policy_con(const POLICY_HND *hnd, struct cli_connection **con)
404 {
405         struct policy *p = find_policy(hnd);
406
407         if (p != NULL && p->open)
408         {
409                 DEBUG(3,("Getting con state pnum=%x\n", p->pnum));
410
411                 if (con != NULL)
412                 {
413                         (*con ) = p->dev.con->con;
414                 }
415
416                 return True;
417         }
418
419         DEBUG(3,("Error getting policy\n"));
420         return False;
421 }
422
423 /****************************************************************************
424   close an lsa policy
425 ****************************************************************************/
426 BOOL close_policy_hnd(POLICY_HND *hnd)
427 {
428         struct policy *p = find_policy(hnd);
429
430         if (!p)
431         {
432                 DEBUG(3,("Error closing policy\n"));
433                 return False;
434         }
435
436         DEBUG(3,("Closed policy name pnum=%x\n",  p->pnum));
437
438         DLIST_REMOVE(Policy, p);
439
440         bitmap_clear(bmap, p->pnum);
441
442         ZERO_STRUCTP(p);
443         ZERO_STRUCTP(hnd);
444
445         switch (p->type)
446         {
447                 case POL_REG_INFO:
448                 {
449                         free(p->dev.reg);
450                         break;
451                 }
452                 case POL_SAMR_INFO:
453                 {
454                         free(p->dev.samr);
455                         break;
456                 }
457                 case POL_CLI_INFO:
458                 {
459                         if (p->dev.con->free != NULL)
460                         {
461                                 p->dev.con->free(p->dev.con->con);
462                         }
463                         free(p->dev.con);
464                         break;
465                 }
466         }
467
468         free(p);
469
470         return True;
471 }
472