~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/rpc_server/srv_lsa_hnd.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 *  Unix SMB/CIFS implementation.
3
 
 *  RPC Pipe client / server routines
4
 
 *  Copyright (C) Andrew Tridgell              1992-1997,
5
 
 *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6
 
 *  Copyright (C) Jeremy Allison                           2001.
7
 
 *  
8
 
 *  This program is free software; you can redistribute it and/or modify
9
 
 *  it under the terms of the GNU General Public License as published by
10
 
 *  the Free Software Foundation; either version 2 of the License, or
11
 
 *  (at your option) any later version.
12
 
 *  
13
 
 *  This program is distributed in the hope that it will be useful,
14
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 *  GNU General Public License for more details.
17
 
 *  
18
 
 *  You should have received a copy of the GNU General Public License
19
 
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
 */
22
 
 
23
 
#include "includes.h"
24
 
 
25
 
#undef DBGC_CLASS
26
 
#define DBGC_CLASS DBGC_RPC_SRV
27
 
 
28
 
/* This is the max handles across all instances of a pipe name. */
29
 
#ifndef MAX_OPEN_POLS
30
 
#define MAX_OPEN_POLS 1024
31
 
#endif
32
 
 
33
 
/****************************************************************************
34
 
 Hack as handles need to be persisant over lsa pipe closes so long as a samr
35
 
 pipe is open. JRA.
36
 
****************************************************************************/
37
 
 
38
 
static BOOL is_samr_lsa_pipe(const char *pipe_name)
39
 
{
40
 
        return (strstr(pipe_name, "samr") || strstr(pipe_name, "lsa"));
41
 
}
42
 
 
43
 
/****************************************************************************
44
 
 Initialise a policy handle list on a pipe. Handle list is shared between all
45
 
 pipes of the same name.
46
 
****************************************************************************/
47
 
 
48
 
BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
49
 
{
50
 
        pipes_struct *plist = get_first_internal_pipe();
51
 
        struct handle_list *hl = NULL;
52
 
 
53
 
        for (plist = get_first_internal_pipe(); plist; plist = get_next_internal_pipe(plist)) {
54
 
                if (strequal( plist->name, pipe_name) ||
55
 
                                (is_samr_lsa_pipe(plist->name) && is_samr_lsa_pipe(pipe_name))) {
56
 
                        if (!plist->pipe_handles) {
57
 
                                pstring msg;
58
 
                                slprintf(msg, sizeof(msg)-1, "init_pipe_handles: NULL pipe_handle pointer in pipe %s",
59
 
                                                pipe_name );
60
 
                                smb_panic(msg);
61
 
                        }
62
 
                        hl = plist->pipe_handles;
63
 
                        break;
64
 
                }
65
 
        }
66
 
 
67
 
        if (!hl) {
68
 
                /*
69
 
                 * No handle list for this pipe (first open of pipe).
70
 
                 * Create list.
71
 
                 */
72
 
 
73
 
                if ((hl = SMB_MALLOC_P(struct handle_list)) == NULL)
74
 
                        return False;
75
 
                ZERO_STRUCTP(hl);
76
 
 
77
 
                DEBUG(10,("init_pipe_handles: created handle list for pipe %s\n", pipe_name ));
78
 
        }
79
 
 
80
 
        /*
81
 
         * One more pipe is using this list.
82
 
         */
83
 
 
84
 
        hl->pipe_ref_count++;
85
 
 
86
 
        /*
87
 
         * Point this pipe at this list.
88
 
         */
89
 
 
90
 
        p->pipe_handles = hl;
91
 
 
92
 
        DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
93
 
                  (unsigned long)p->pipe_handles->pipe_ref_count, pipe_name ));
94
 
 
95
 
        return True;
96
 
}
97
 
 
98
 
/****************************************************************************
99
 
  find first available policy slot.  creates a policy handle for you.
100
 
****************************************************************************/
101
 
 
102
 
BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *), void *data_ptr)
103
 
{
104
 
        static uint32 pol_hnd_low  = 0;
105
 
        static uint32 pol_hnd_high = 0;
106
 
 
107
 
        struct policy *pol;
108
 
 
109
 
        if (p->pipe_handles->count > MAX_OPEN_POLS) {
110
 
                DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
111
 
                                (int)p->pipe_handles->count));
112
 
                return False;
113
 
        }
114
 
 
115
 
        pol = SMB_MALLOC_P(struct policy);
116
 
        if (!pol) {
117
 
                DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n"));
118
 
                return False;
119
 
        }
120
 
 
121
 
        ZERO_STRUCTP(pol);
122
 
 
123
 
        pol->data_ptr = data_ptr;
124
 
        pol->free_fn = free_fn;
125
 
 
126
 
        pol_hnd_low++;
127
 
        if (pol_hnd_low == 0)
128
 
                (pol_hnd_high)++;
129
 
 
130
 
        SIVAL(&pol->pol_hnd.data1, 0 , 0);  /* first bit must be null */
131
 
        SIVAL(&pol->pol_hnd.data2, 0 , pol_hnd_low ); /* second bit is incrementing */
132
 
        SSVAL(&pol->pol_hnd.data3, 0 , pol_hnd_high); /* second bit is incrementing */
133
 
        SSVAL(&pol->pol_hnd.data4, 0 , (pol_hnd_high>>16)); /* second bit is incrementing */
134
 
        SIVAL(pol->pol_hnd.data5, 0, time(NULL)); /* something random */
135
 
        SIVAL(pol->pol_hnd.data5, 4, sys_getpid()); /* something more random */
136
 
 
137
 
        DLIST_ADD(p->pipe_handles->Policy, pol);
138
 
        p->pipe_handles->count++;
139
 
 
140
 
        *hnd = pol->pol_hnd;
141
 
        
142
 
        DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
143
 
        dump_data(4, (char *)hnd, sizeof(*hnd));
144
 
 
145
 
        return True;
146
 
}
147
 
 
148
 
/****************************************************************************
149
 
  find policy by handle - internal version.
150
 
****************************************************************************/
151
 
 
152
 
static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *hnd, void **data_p)
153
 
{
154
 
        struct policy *pol;
155
 
        size_t i;
156
 
 
157
 
        if (data_p)
158
 
                *data_p = NULL;
159
 
 
160
 
        for (i = 0, pol=p->pipe_handles->Policy;pol;pol=pol->next, i++) {
161
 
                if (memcmp(&pol->pol_hnd, hnd, sizeof(*hnd)) == 0) {
162
 
                        DEBUG(4,("Found policy hnd[%d] ", (int)i));
163
 
                        dump_data(4, (char *)hnd, sizeof(*hnd));
164
 
                        if (data_p)
165
 
                                *data_p = pol->data_ptr;
166
 
                        return pol;
167
 
                }
168
 
        }
169
 
 
170
 
        DEBUG(4,("Policy not found: "));
171
 
        dump_data(4, (char *)hnd, sizeof(*hnd));
172
 
 
173
 
        p->bad_handle_fault_state = True;
174
 
 
175
 
        return NULL;
176
 
}
177
 
 
178
 
/****************************************************************************
179
 
  find policy by handle
180
 
****************************************************************************/
181
 
 
182
 
BOOL find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p)
183
 
{
184
 
        return find_policy_by_hnd_internal(p, hnd, data_p) == NULL ? False : True;
185
 
}
186
 
 
187
 
/****************************************************************************
188
 
  Close a policy.
189
 
****************************************************************************/
190
 
 
191
 
BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd)
192
 
{
193
 
        struct policy *pol = find_policy_by_hnd_internal(p, hnd, NULL);
194
 
 
195
 
        if (!pol) {
196
 
                DEBUG(3,("Error closing policy\n"));
197
 
                return False;
198
 
        }
199
 
 
200
 
        DEBUG(3,("Closed policy\n"));
201
 
 
202
 
        if (pol->free_fn && pol->data_ptr)
203
 
                (*pol->free_fn)(pol->data_ptr);
204
 
 
205
 
        p->pipe_handles->count--;
206
 
 
207
 
        DLIST_REMOVE(p->pipe_handles->Policy, pol);
208
 
 
209
 
        ZERO_STRUCTP(pol);
210
 
 
211
 
        SAFE_FREE(pol);
212
 
 
213
 
        return True;
214
 
}
215
 
 
216
 
/****************************************************************************
217
 
 Close a pipe - free the handle list if it was the last pipe reference.
218
 
****************************************************************************/
219
 
 
220
 
void close_policy_by_pipe(pipes_struct *p)
221
 
{
222
 
        p->pipe_handles->pipe_ref_count--;
223
 
 
224
 
        if (p->pipe_handles->pipe_ref_count == 0) {
225
 
                /*
226
 
                 * Last pipe open on this list - free the list.
227
 
                 */
228
 
                while (p->pipe_handles->Policy)
229
 
                        close_policy_hnd(p, &p->pipe_handles->Policy->pol_hnd);
230
 
 
231
 
                p->pipe_handles->Policy = NULL;
232
 
                p->pipe_handles->count = 0;
233
 
 
234
 
                SAFE_FREE(p->pipe_handles);
235
 
                DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name ));
236
 
        }
237
 
}
238
 
 
239
 
/*******************************************************************
240
 
Shall we allow access to this rpc?  Currently this function
241
 
implements the 'restrict anonymous' setting by denying access to
242
 
anonymous users if the restrict anonymous level is > 0.  Further work
243
 
will be checking a security descriptor to determine whether a user
244
 
token has enough access to access the pipe.
245
 
********************************************************************/
246
 
 
247
 
BOOL pipe_access_check(pipes_struct *p)
248
 
{
249
 
        /* Don't let anonymous users access this RPC if restrict
250
 
           anonymous > 0 */
251
 
 
252
 
        if (lp_restrict_anonymous() > 0) {
253
 
                user_struct *user = get_valid_user_struct(p->vuid);
254
 
 
255
 
                /* schannel, so we must be ok */
256
 
                if (p->pipe_bound && (p->auth.auth_type == PIPE_AUTH_TYPE_SCHANNEL)) {
257
 
                        return True;
258
 
                }
259
 
 
260
 
                if (!user) {
261
 
                        DEBUG(3, ("invalid vuid %d\n", p->vuid));
262
 
                        return False;
263
 
                }
264
 
 
265
 
                if (user->guest) {
266
 
                        return False;
267
 
                }
268
 
        }
269
 
 
270
 
        return True;
271
 
}