cool! completed a samr* API that _would_ look like an msdn samr* api...
[ira/wip.git] / source3 / rpc_server / srv_lsa_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 cli_info
54 {
55         struct cli_state *cli;
56         uint16 fnum;
57         void (*free)(struct cli_state*, uint16 fnum);
58 };
59
60 static struct policy
61 {
62         struct policy *next, *prev;
63         int pnum;
64         BOOL open;
65         POLICY_HND pol_hnd;
66         int type;
67
68         union {
69                 struct samr_info *samr;
70                 struct reg_info *reg;
71                 struct cli_info *cli;
72
73         } dev;
74
75 } *Policy;
76
77 static struct bitmap *bmap;
78
79
80 /****************************************************************************
81   create a unique policy handle
82 ****************************************************************************/
83 static void create_pol_hnd(POLICY_HND *hnd)
84 {
85         static uint32 pol_hnd_low  = 0;
86         static uint32 pol_hnd_high = 0;
87
88         if (hnd == NULL) return;
89
90         /* i severely doubt that pol_hnd_high will ever be non-zero... */
91         pol_hnd_low++;
92         if (pol_hnd_low == 0) pol_hnd_high++;
93
94         SIVAL(hnd->data, 0 , 0x0);  /* first bit must be null */
95         SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
96         SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
97         SIVAL(hnd->data, 12, time(NULL)); /* something random */
98         SIVAL(hnd->data, 16, getpid()); /* something more random */
99 }
100
101 /****************************************************************************
102   initialise policy handle states...
103 ****************************************************************************/
104 BOOL init_policy_hnd(int num_pol_hnds)
105 {
106         bmap = bitmap_allocate(num_pol_hnds);
107         
108         return bmap != NULL;
109 }
110
111 /****************************************************************************
112   find first available policy slot.  creates a policy handle for you.
113 ****************************************************************************/
114 BOOL register_policy_hnd(POLICY_HND *hnd)
115 {
116         int i;
117         struct policy *p;
118
119         i = bitmap_find(bmap, 1);
120
121         if (i == -1) {
122                 DEBUG(0,("ERROR: out of Policy Handles!\n"));
123                 return False;
124         }
125
126         p = (struct policy *)malloc(sizeof(*p));
127         if (!p) {
128                 DEBUG(0,("ERROR: out of memory!\n"));
129                 return False;
130         }
131
132         ZERO_STRUCTP(p);
133
134         p->open = True;                         
135         p->pnum = i;
136         p->type = POL_NO_INFO;
137
138         memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
139
140         bitmap_set(bmap, i);
141
142         DLIST_ADD(Policy, p);
143         
144         DEBUG(4,("Opened policy hnd[%x] ", i));
145         dump_data(4, (char *)hnd->data, sizeof(hnd->data));
146
147         return True;
148 }
149
150 /****************************************************************************
151   find first available policy slot.  creates a policy handle for you.
152 ****************************************************************************/
153 BOOL open_policy_hnd(POLICY_HND *hnd)
154 {
155         create_pol_hnd(hnd);
156         return register_policy_hnd(hnd);
157 }
158
159 /****************************************************************************
160   find policy by handle
161 ****************************************************************************/
162 static struct policy *find_policy(const POLICY_HND *hnd)
163 {
164         struct policy *p;
165
166         for (p=Policy;p;p=p->next) {
167                 if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
168                         DEBUG(4,("Found policy hnd[%x] ", p->pnum));
169                         dump_data(4, (const char *)hnd->data,
170                         sizeof(hnd->data));
171                         return p;
172                 }
173         }
174
175         DEBUG(4,("Policy not found: "));
176         dump_data(4, (const char *)hnd->data, sizeof(hnd->data));
177
178         return NULL;
179 }
180
181 /****************************************************************************
182   find policy index by handle
183 ****************************************************************************/
184 int find_policy_by_hnd(const POLICY_HND *hnd)
185 {
186         struct policy *p = find_policy(hnd);
187
188         return p?p->pnum:-1;
189 }
190
191 /****************************************************************************
192   set samr rid
193 ****************************************************************************/
194 BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
195 {
196         struct policy *p = find_policy(hnd);
197
198         if (p && p->open)
199         {
200                 DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
201                          rid, p->pnum));
202
203                 if (p->dev.samr == NULL)
204                 {
205                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
206                 }
207                 if (p->dev.samr == NULL)
208                 {
209                         return False;
210                 }
211                 p->dev.samr->rid = rid;
212                 return True;
213         }
214
215         DEBUG(3,("Error setting policy rid=%x\n",rid));
216         return False;
217 }
218
219
220 /****************************************************************************
221   set samr pol status.  absolutely no idea what this is.
222 ****************************************************************************/
223 BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
224 {
225         struct policy *p = find_policy(hnd);
226
227         if (p && p->open)
228         {
229                 DEBUG(3,("Setting policy status=%x pnum=%x\n",
230                           pol_status, p->pnum));
231
232                 if (p->dev.samr == NULL)
233                 {
234                         p->type = POL_SAMR_INFO;
235                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
236                 }
237                 if (p->dev.samr == NULL)
238                 {
239                         return False;
240                 }
241                 p->dev.samr->status = pol_status;
242                 return True;
243         } 
244
245         DEBUG(3,("Error setting policy status=%x\n",
246                  pol_status));
247         return False;
248 }
249
250 /****************************************************************************
251   set samr sid
252 ****************************************************************************/
253 BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
254 {
255         pstring sidstr;
256         struct policy *p = find_policy(hnd);
257
258         if (p && p->open) {
259                 DEBUG(3,("Setting policy sid=%s pnum=%x\n",
260                          sid_to_string(sidstr, sid), p->pnum));
261
262                 if (p->dev.samr == NULL)
263                 {
264                         p->type = POL_SAMR_INFO;
265                         p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
266                 }
267                 if (p->dev.samr == NULL)
268                 {
269                         return False;
270                 }
271                 memcpy(&p->dev.samr->sid, sid, sizeof(*sid));
272                 return True;
273         }
274
275         DEBUG(3,("Error setting policy sid=%s\n",
276                   sid_to_string(sidstr, sid)));
277         return False;
278 }
279
280 /****************************************************************************
281   get samr sid
282 ****************************************************************************/
283 BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
284 {
285         struct policy *p = find_policy(hnd);
286
287         if (p != NULL && p->open)
288         {
289                 pstring sidstr;
290                 memcpy(sid, &p->dev.samr->sid, sizeof(*sid));
291                 DEBUG(3,("Getting policy sid=%s pnum=%x\n",
292                          sid_to_string(sidstr, sid), p->pnum));
293
294                 return True;
295         }
296
297         DEBUG(3,("Error getting policy\n"));
298         return False;
299 }
300
301 /****************************************************************************
302   get samr rid
303 ****************************************************************************/
304 uint32 get_policy_samr_rid(POLICY_HND *hnd)
305 {
306         struct policy *p = find_policy(hnd);
307
308         if (p && p->open) {
309                 uint32 rid = p->dev.samr->rid;
310                 DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
311                           rid, p->pnum));
312
313                 return rid;
314         }
315
316         DEBUG(3,("Error getting policy\n"));
317         return 0xffffffff;
318 }
319
320 /****************************************************************************
321   set reg name 
322 ****************************************************************************/
323 BOOL set_policy_reg_name(POLICY_HND *hnd, fstring name)
324 {
325         struct policy *p = find_policy(hnd);
326
327         if (p && p->open)
328         {
329                 DEBUG(3,("Getting policy pnum=%x\n",
330                          p->pnum));
331
332                 if (p->dev.reg == NULL)
333                 {
334                         p->type = POL_REG_INFO;
335                         p->dev.reg = (struct reg_info*)malloc(sizeof(*p->dev.reg));
336                 }
337                 if (p->dev.reg == NULL)
338                 {
339                         return False;
340                 }
341                 fstrcpy(p->dev.reg->name, name);
342                 return True;
343         }
344
345         DEBUG(3,("Error setting policy name=%s\n", name));
346         return False;
347 }
348
349 /****************************************************************************
350   set reg name 
351 ****************************************************************************/
352 BOOL get_policy_reg_name(POLICY_HND *hnd, fstring name)
353 {
354         struct policy *p = find_policy(hnd);
355
356         if (p && p->open)
357         {
358                 DEBUG(3,("Setting policy pnum=%x name=%s\n",
359                          p->pnum, name));
360
361                 fstrcpy(name, p->dev.reg->name);
362                 DEBUG(5,("getting policy reg name=%s\n", name));
363                 return True;
364         }
365
366         DEBUG(3,("Error getting policy reg name\n"));
367         return False;
368 }
369
370 /****************************************************************************
371   set cli state
372 ****************************************************************************/
373 BOOL set_policy_cli_state(POLICY_HND *hnd, struct cli_state *cli, uint16 fnum,
374                                 void (*free_fn)(struct cli_state *, uint16))
375 {
376         struct policy *p = find_policy(hnd);
377
378         if (p && p->open)
379         {
380                 DEBUG(3,("Setting policy cli state pnum=%x\n", p->pnum));
381
382                 if (p->dev.cli == NULL)
383                 {
384                         p->type = POL_CLI_INFO;
385                         p->dev.cli = (struct cli_info*)malloc(sizeof(*p->dev.cli));
386                 }
387                 if (p->dev.cli == NULL)
388                 {
389                         return False;
390                 }
391                 p->dev.cli->cli  = cli;
392                 p->dev.cli->free = free_fn;
393                 p->dev.cli->fnum = fnum;
394                 return True;
395         }
396
397         DEBUG(3,("Error setting policy cli state\n"));
398
399         return False;
400 }
401
402 /****************************************************************************
403   get cli state
404 ****************************************************************************/
405 BOOL get_policy_cli_state(const POLICY_HND *hnd, struct cli_state **cli,
406         uint16 *fnum)
407 {
408         struct policy *p = find_policy(hnd);
409
410         if (p != NULL && p->open)
411         {
412                 DEBUG(3,("Getting cli state pnum=%x\n", p->pnum));
413
414                 if (cli != NULL)
415                 {
416                         (*cli ) = p->dev.cli->cli;
417                 }
418                 if (fnum != NULL)
419                 {
420                         (*fnum) = p->dev.cli->fnum;
421                 }
422
423                 return True;
424         }
425
426         DEBUG(3,("Error getting policy\n"));
427         return False;
428 }
429
430 /****************************************************************************
431   close an lsa policy
432 ****************************************************************************/
433 BOOL close_policy_hnd(POLICY_HND *hnd)
434 {
435         struct policy *p = find_policy(hnd);
436
437         if (!p)
438         {
439                 DEBUG(3,("Error closing policy\n"));
440                 return False;
441         }
442
443         DEBUG(3,("Closed policy name pnum=%x\n",  p->pnum));
444
445         DLIST_REMOVE(Policy, p);
446
447         bitmap_clear(bmap, p->pnum);
448
449         ZERO_STRUCTP(p);
450         ZERO_STRUCTP(hnd);
451
452         switch (p->type)
453         {
454                 case POL_REG_INFO:
455                 {
456                         free(p->dev.reg);
457                         break;
458                 }
459                 case POL_SAMR_INFO:
460                 {
461                         free(p->dev.samr);
462                         break;
463                 }
464                 case POL_CLI_INFO:
465                 {
466                         if (p->dev.cli->free != NULL)
467                         {
468                                 p->dev.cli->free(p->dev.cli->cli,
469                                                  p->dev.cli->fnum);
470                         }
471                         free(p->dev.cli);
472                         break;
473                 }
474         }
475
476         free(p);
477
478         return True;
479 }
480