~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/rpc_server/srv_dfs_nt.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 for Dfs
4
 
 *  Copyright (C) Shirish Kalele        2000.
5
 
 *  Copyright (C) Jeremy Allison        2001.
6
 
 *  Copyright (C) Jelmer Vernooij       2005.
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
 
/* This is the implementation of the dfs pipe. */
24
 
 
25
 
#include "includes.h"
26
 
 
27
 
#undef DBGC_CLASS
28
 
#define DBGC_CLASS DBGC_MSDFS
29
 
 
30
 
/* This function does not return a WERROR or NTSTATUS code but rather 1 if
31
 
   dfs exists, or 0 otherwise. */
32
 
 
33
 
uint32 _dfs_GetManagerVersion(pipes_struct *p, NETDFS_Q_DFS_GETMANAGERVERSION *q_u, NETDFS_R_DFS_GETMANAGERVERSION *r_u)
34
 
{
35
 
        if(lp_host_msdfs()) 
36
 
                return 1;
37
 
        else
38
 
                return 0;
39
 
}
40
 
 
41
 
WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u)
42
 
{
43
 
        struct junction_map jn;
44
 
        struct referral* old_referral_list = NULL;
45
 
        BOOL exists = False;
46
 
 
47
 
        pstring dfspath, servername, sharename;
48
 
        pstring altpath;
49
 
 
50
 
        if (p->pipe_user.ut.uid != 0) {
51
 
                DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
52
 
                return WERR_ACCESS_DENIED;
53
 
        }
54
 
 
55
 
        unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1);
56
 
        unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1);
57
 
        unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1);
58
 
 
59
 
        DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n",
60
 
                dfspath, servername, sharename));
61
 
 
62
 
        pstrcpy(altpath, servername);
63
 
        pstrcat(altpath, "\\");
64
 
        pstrcat(altpath, sharename);
65
 
 
66
 
        /* The following call can change the cwd. */
67
 
        if(get_referred_path(p->mem_ctx, dfspath, &jn, NULL, NULL)) {
68
 
                exists = True;
69
 
                jn.referral_count += 1;
70
 
                old_referral_list = jn.referral_list;
71
 
        } else {
72
 
                jn.referral_count = 1;
73
 
        }
74
 
 
75
 
        vfs_ChDir(p->conn,p->conn->connectpath);
76
 
 
77
 
        jn.referral_list = TALLOC_ARRAY(p->mem_ctx, struct referral, jn.referral_count);
78
 
        if(jn.referral_list == NULL) {
79
 
                DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
80
 
                return WERR_DFS_INTERNAL_ERROR;
81
 
        }
82
 
 
83
 
        if(old_referral_list) {
84
 
                memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1);
85
 
        }
86
 
  
87
 
        jn.referral_list[jn.referral_count-1].proximity = 0;
88
 
        jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL;
89
 
 
90
 
        pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
91
 
  
92
 
        if(!create_msdfs_link(&jn, exists)) {
93
 
                vfs_ChDir(p->conn,p->conn->connectpath);
94
 
                return WERR_DFS_CANT_CREATE_JUNCT;
95
 
        }
96
 
        vfs_ChDir(p->conn,p->conn->connectpath);
97
 
 
98
 
        return WERR_OK;
99
 
}
100
 
 
101
 
WERROR _dfs_Remove(pipes_struct *p, NETDFS_Q_DFS_REMOVE *q_u, 
102
 
                   NETDFS_R_DFS_REMOVE *r_u)
103
 
{
104
 
        struct junction_map jn;
105
 
        BOOL found = False;
106
 
 
107
 
        pstring dfspath, servername, sharename;
108
 
        pstring altpath;
109
 
 
110
 
        if (p->pipe_user.ut.uid != 0) {
111
 
                DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
112
 
                return WERR_ACCESS_DENIED;
113
 
        }
114
 
 
115
 
        unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1);
116
 
        if(q_u->ptr0_server) {
117
 
                unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1);
118
 
        }
119
 
 
120
 
        if(q_u->ptr0_share) {
121
 
                unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1);
122
 
        }
123
 
 
124
 
        if(q_u->ptr0_server && q_u->ptr0_share) {
125
 
                pstrcpy(altpath, servername);
126
 
                pstrcat(altpath, "\\");
127
 
                pstrcat(altpath, sharename);
128
 
                strlower_m(altpath);
129
 
        }
130
 
 
131
 
        DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
132
 
                dfspath, servername, sharename));
133
 
 
134
 
        if(!get_referred_path(p->mem_ctx, dfspath, &jn, NULL, NULL)) {
135
 
                return WERR_DFS_NO_SUCH_VOL;
136
 
        }
137
 
 
138
 
        /* if no server-share pair given, remove the msdfs link completely */
139
 
        if(!q_u->ptr0_server && !q_u->ptr0_share) {
140
 
                if(!remove_msdfs_link(&jn)) {
141
 
                        vfs_ChDir(p->conn,p->conn->connectpath);
142
 
                        return WERR_DFS_NO_SUCH_VOL;
143
 
                }
144
 
                vfs_ChDir(p->conn,p->conn->connectpath);
145
 
        } else {
146
 
                int i=0;
147
 
                /* compare each referral in the list with the one to remove */
148
 
                DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
149
 
                for(i=0;i<jn.referral_count;i++) {
150
 
                        pstring refpath;
151
 
                        pstrcpy(refpath,jn.referral_list[i].alternate_path);
152
 
                        trim_char(refpath, '\\', '\\');
153
 
                        DEBUG(10,("_dfs_remove:  refpath: .%s.\n", refpath));
154
 
                        if(strequal(refpath, altpath)) {
155
 
                                *(jn.referral_list[i].alternate_path)='\0';
156
 
                                DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
157
 
                                        refpath));
158
 
                                found = True;
159
 
                        }
160
 
                }
161
 
 
162
 
                if(!found) {
163
 
                        return WERR_DFS_NO_SUCH_SHARE;
164
 
                }
165
 
 
166
 
                /* Only one referral, remove it */
167
 
                if(jn.referral_count == 1) {
168
 
                        if(!remove_msdfs_link(&jn)) {
169
 
                                vfs_ChDir(p->conn,p->conn->connectpath);
170
 
                                return WERR_DFS_NO_SUCH_VOL;
171
 
                        }
172
 
                } else {
173
 
                        if(!create_msdfs_link(&jn, True)) { 
174
 
                                vfs_ChDir(p->conn,p->conn->connectpath);
175
 
                                return WERR_DFS_CANT_CREATE_JUNCT;
176
 
                        }
177
 
                }
178
 
                vfs_ChDir(p->conn,p->conn->connectpath);
179
 
        }
180
 
 
181
 
        return WERR_OK;
182
 
}
183
 
 
184
 
static BOOL init_reply_dfs_info_1(struct junction_map* j, NETDFS_DFS_INFO1* dfs1)
185
 
{
186
 
        pstring str;
187
 
        dfs1->ptr0_path = 1;
188
 
        slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(), 
189
 
                j->service_name, j->volume_name);
190
 
        DEBUG(5,("init_reply_dfs_info_1: initing entrypath: %s\n",str));
191
 
        init_unistr2(&dfs1->path,str,UNI_STR_TERMINATE);
192
 
        return True;
193
 
}
194
 
 
195
 
static BOOL init_reply_dfs_info_2(struct junction_map* j, NETDFS_DFS_INFO2* dfs2)
196
 
{
197
 
        pstring str;
198
 
        dfs2->ptr0_path = 1;
199
 
        slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
200
 
                j->service_name, j->volume_name);
201
 
        init_unistr2(&dfs2->path, str, UNI_STR_TERMINATE);
202
 
        dfs2->ptr0_comment = 0;
203
 
        dfs2->state = 1; /* set up state of dfs junction as OK */
204
 
        dfs2->num_stores = j->referral_count;
205
 
        return True;
206
 
}
207
 
 
208
 
static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, NETDFS_DFS_INFO3* dfs3)
209
 
{
210
 
        int ii;
211
 
        pstring str;
212
 
        dfs3->ptr0_path = 1;
213
 
        if (j->volume_name[0] == '\0')
214
 
                slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
215
 
                        global_myname(), j->service_name);
216
 
        else
217
 
                slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
218
 
                        j->service_name, j->volume_name);
219
 
 
220
 
        init_unistr2(&dfs3->path, str, UNI_STR_TERMINATE);
221
 
        dfs3->ptr0_comment = 1;
222
 
        init_unistr2(&dfs3->comment, "", UNI_STR_TERMINATE);
223
 
        dfs3->state = 1;
224
 
        dfs3->num_stores = dfs3->size_stores = j->referral_count;
225
 
        dfs3->ptr0_stores = 1;
226
 
    
227
 
        /* also enumerate the stores */
228
 
        dfs3->stores = TALLOC_ARRAY(ctx, NETDFS_DFS_STORAGEINFO, j->referral_count);
229
 
        if (!dfs3->stores)
230
 
                return False;
231
 
 
232
 
        memset(dfs3->stores, '\0', j->referral_count * sizeof(NETDFS_DFS_STORAGEINFO));
233
 
 
234
 
        for(ii=0;ii<j->referral_count;ii++) {
235
 
                char* p; 
236
 
                pstring path;
237
 
                NETDFS_DFS_STORAGEINFO* stor = &(dfs3->stores[ii]);
238
 
                struct referral* ref = &(j->referral_list[ii]);
239
 
  
240
 
                pstrcpy(path, ref->alternate_path);
241
 
                trim_char(path,'\\','\0');
242
 
                p = strrchr_m(path,'\\');
243
 
                if(p==NULL) {
244
 
                        DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path));
245
 
                        continue;
246
 
                }
247
 
                *p = '\0';
248
 
                DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1));
249
 
                stor->state = 2; /* set all stores as ONLINE */
250
 
                init_unistr2(&stor->server, path, UNI_STR_TERMINATE);
251
 
                init_unistr2(&stor->share,  p+1, UNI_STR_TERMINATE);
252
 
                stor->ptr0_server = stor->ptr0_share = 1;
253
 
        }
254
 
        return True;
255
 
}
256
 
 
257
 
WERROR _dfs_Enum(pipes_struct *p, NETDFS_Q_DFS_ENUM *q_u, NETDFS_R_DFS_ENUM *r_u)
258
 
{
259
 
        uint32 level = q_u->level;
260
 
        struct junction_map jn[MAX_MSDFS_JUNCTIONS];
261
 
        int num_jn = 0;
262
 
        int i;
263
 
 
264
 
        num_jn = enum_msdfs_links(p->mem_ctx, jn, ARRAY_SIZE(jn));
265
 
        vfs_ChDir(p->conn,p->conn->connectpath);
266
 
    
267
 
        DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
268
 
 
269
 
        r_u->ptr0_info = q_u->ptr0_info;
270
 
        r_u->ptr0_total = q_u->ptr0_total;
271
 
        r_u->total = num_jn;
272
 
 
273
 
        r_u->info = q_u->info;
274
 
 
275
 
        /* Create the return array */
276
 
        switch (level) {
277
 
        case 1:
278
 
                if ((r_u->info.e.u.info1.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO1, num_jn)) == NULL) {
279
 
                        return WERR_NOMEM;
280
 
                }
281
 
                r_u->info.e.u.info1.count = num_jn;
282
 
                r_u->info.e.u.info1.ptr0_s = 1;
283
 
                r_u->info.e.u.info1.size_s = num_jn;
284
 
                break;
285
 
        case 2:
286
 
                if ((r_u->info.e.u.info2.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO2, num_jn)) == NULL) {
287
 
                        return WERR_NOMEM;
288
 
                }
289
 
                r_u->info.e.u.info2.count = num_jn;
290
 
                r_u->info.e.u.info2.ptr0_s = 1;
291
 
                r_u->info.e.u.info2.size_s = num_jn;
292
 
                break;
293
 
        case 3:
294
 
                if ((r_u->info.e.u.info3.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO3, num_jn)) == NULL) {
295
 
                        return WERR_NOMEM;
296
 
                }
297
 
                r_u->info.e.u.info3.count = num_jn;
298
 
                r_u->info.e.u.info3.ptr0_s = 1;
299
 
                r_u->info.e.u.info3.size_s = num_jn;
300
 
                break;
301
 
        default:
302
 
                return WERR_INVALID_PARAM;
303
 
        }
304
 
 
305
 
        for (i = 0; i < num_jn; i++) {
306
 
                switch (level) {
307
 
                case 1: 
308
 
                        init_reply_dfs_info_1(&jn[i], &r_u->info.e.u.info1.s[i]);
309
 
                        break;
310
 
                case 2:
311
 
                        init_reply_dfs_info_2(&jn[i], &r_u->info.e.u.info2.s[i]);
312
 
                        break;
313
 
                case 3:
314
 
                        init_reply_dfs_info_3(p->mem_ctx, &jn[i], &r_u->info.e.u.info3.s[i]);
315
 
                        break;
316
 
                default:
317
 
                        return WERR_INVALID_PARAM;
318
 
                }
319
 
        }
320
 
  
321
 
        r_u->status = WERR_OK;
322
 
 
323
 
        return r_u->status;
324
 
}
325
 
      
326
 
WERROR _dfs_GetInfo(pipes_struct *p, NETDFS_Q_DFS_GETINFO *q_u, 
327
 
                     NETDFS_R_DFS_GETINFO *r_u)
328
 
{
329
 
        UNISTR2* uni_path = &q_u->path;
330
 
        uint32 level = q_u->level;
331
 
        int consumedcnt = sizeof(pstring);
332
 
        pstring path;
333
 
        BOOL ret;
334
 
        struct junction_map jn;
335
 
 
336
 
        unistr2_to_ascii(path, uni_path, sizeof(path)-1);
337
 
        if(!create_junction(path, &jn))
338
 
                return WERR_DFS_NO_SUCH_SERVER;
339
 
  
340
 
        /* The following call can change the cwd. */
341
 
        if(!get_referred_path(p->mem_ctx, path, &jn, &consumedcnt, NULL) || consumedcnt < strlen(path)) {
342
 
                vfs_ChDir(p->conn,p->conn->connectpath);
343
 
                return WERR_DFS_NO_SUCH_VOL;
344
 
        }
345
 
 
346
 
        vfs_ChDir(p->conn,p->conn->connectpath);
347
 
        r_u->info.switch_value = level;
348
 
        r_u->info.ptr0 = 1;
349
 
        r_u->status = WERR_OK;
350
 
 
351
 
        switch (level) {
352
 
                case 1: ret = init_reply_dfs_info_1(&jn, &r_u->info.u.info1); break;
353
 
                case 2: ret = init_reply_dfs_info_2(&jn, &r_u->info.u.info2); break;
354
 
                case 3: ret = init_reply_dfs_info_3(p->mem_ctx, &jn, &r_u->info.u.info3); break;
355
 
                default:
356
 
                        ret = False;
357
 
                        break;
358
 
        }
359
 
 
360
 
        if (!ret) 
361
 
                r_u->status = WERR_INVALID_PARAM;
362
 
  
363
 
        return r_u->status;
364
 
}
365
 
 
366
 
WERROR _dfs_SetInfo(pipes_struct *p, NETDFS_Q_DFS_SETINFO *q_u, NETDFS_R_DFS_SETINFO *r_u)
367
 
{
368
 
        /* FIXME: Implement your code here */
369
 
        return WERR_NOT_SUPPORTED;
370
 
}
371
 
 
372
 
WERROR _dfs_Rename(pipes_struct *p, NETDFS_Q_DFS_RENAME *q_u, NETDFS_R_DFS_RENAME *r_u)
373
 
{
374
 
        /* FIXME: Implement your code here */
375
 
        return WERR_NOT_SUPPORTED;
376
 
}
377
 
 
378
 
WERROR _dfs_Move(pipes_struct *p, NETDFS_Q_DFS_MOVE *q_u, NETDFS_R_DFS_MOVE *r_u)
379
 
{
380
 
        /* FIXME: Implement your code here */
381
 
        return WERR_NOT_SUPPORTED;
382
 
}
383
 
 
384
 
WERROR _dfs_ManagerGetConfigInfo(pipes_struct *p, NETDFS_Q_DFS_MANAGERGETCONFIGINFO *q_u, NETDFS_R_DFS_MANAGERGETCONFIGINFO *r_u)
385
 
{
386
 
        /* FIXME: Implement your code here */
387
 
        return WERR_NOT_SUPPORTED;
388
 
}
389
 
 
390
 
WERROR _dfs_ManagerSendSiteInfo(pipes_struct *p, NETDFS_Q_DFS_MANAGERSENDSITEINFO *q_u, NETDFS_R_DFS_MANAGERSENDSITEINFO *r_u)
391
 
{
392
 
        /* FIXME: Implement your code here */
393
 
        return WERR_NOT_SUPPORTED;
394
 
}
395
 
 
396
 
WERROR _dfs_AddFtRoot(pipes_struct *p, NETDFS_Q_DFS_ADDFTROOT *q_u, NETDFS_R_DFS_ADDFTROOT *r_u)
397
 
{
398
 
        /* FIXME: Implement your code here */
399
 
        return WERR_NOT_SUPPORTED;
400
 
}
401
 
 
402
 
WERROR _dfs_RemoveFtRoot(pipes_struct *p, NETDFS_Q_DFS_REMOVEFTROOT *q_u, NETDFS_R_DFS_REMOVEFTROOT *r_u)
403
 
{
404
 
        /* FIXME: Implement your code here */
405
 
        return WERR_NOT_SUPPORTED;
406
 
}
407
 
 
408
 
WERROR _dfs_AddStdRoot(pipes_struct *p, NETDFS_Q_DFS_ADDSTDROOT *q_u, NETDFS_R_DFS_ADDSTDROOT *r_u)
409
 
{
410
 
        /* FIXME: Implement your code here */
411
 
        return WERR_NOT_SUPPORTED;
412
 
}
413
 
 
414
 
WERROR _dfs_RemoveStdRoot(pipes_struct *p, NETDFS_Q_DFS_REMOVESTDROOT *q_u, NETDFS_R_DFS_REMOVESTDROOT *r_u)
415
 
{
416
 
        /* FIXME: Implement your code here */
417
 
        return WERR_NOT_SUPPORTED;
418
 
}
419
 
 
420
 
WERROR _dfs_ManagerInitialize(pipes_struct *p, NETDFS_Q_DFS_MANAGERINITIALIZE *q_u, NETDFS_R_DFS_MANAGERINITIALIZE *r_u)
421
 
{
422
 
        /* FIXME: Implement your code here */
423
 
        return WERR_NOT_SUPPORTED;
424
 
}
425
 
 
426
 
WERROR _dfs_AddStdRootForced(pipes_struct *p, NETDFS_Q_DFS_ADDSTDROOTFORCED *q_u, NETDFS_R_DFS_ADDSTDROOTFORCED *r_u)
427
 
{
428
 
        /* FIXME: Implement your code here */
429
 
        return WERR_NOT_SUPPORTED;
430
 
}
431
 
 
432
 
WERROR _dfs_GetDcAddress(pipes_struct *p, NETDFS_Q_DFS_GETDCADDRESS *q_u, NETDFS_R_DFS_GETDCADDRESS *r_u)
433
 
{
434
 
        /* FIXME: Implement your code here */
435
 
        return WERR_NOT_SUPPORTED;
436
 
}
437
 
 
438
 
WERROR _dfs_SetDcAddress(pipes_struct *p, NETDFS_Q_DFS_SETDCADDRESS *q_u, NETDFS_R_DFS_SETDCADDRESS *r_u)
439
 
{
440
 
        /* FIXME: Implement your code here */
441
 
        return WERR_NOT_SUPPORTED;
442
 
}
443
 
 
444
 
WERROR _dfs_FlushFtTable(pipes_struct *p, NETDFS_Q_DFS_FLUSHFTTABLE *q_u, NETDFS_R_DFS_FLUSHFTTABLE *r_u)
445
 
{
446
 
        /* FIXME: Implement your code here */
447
 
        return WERR_NOT_SUPPORTED;
448
 
}
449
 
 
450
 
WERROR _dfs_Add2(pipes_struct *p, NETDFS_Q_DFS_ADD2 *q_u, NETDFS_R_DFS_ADD2 *r_u)
451
 
{
452
 
        /* FIXME: Implement your code here */
453
 
        return WERR_NOT_SUPPORTED;
454
 
}
455
 
 
456
 
WERROR _dfs_Remove2(pipes_struct *p, NETDFS_Q_DFS_REMOVE2 *q_u, NETDFS_R_DFS_REMOVE2 *r_u)
457
 
{
458
 
        /* FIXME: Implement your code here */
459
 
        return WERR_NOT_SUPPORTED;
460
 
}
461
 
 
462
 
WERROR _dfs_EnumEx(pipes_struct *p, NETDFS_Q_DFS_ENUMEX *q_u, NETDFS_R_DFS_ENUMEX *r_u)
463
 
{
464
 
        /* FIXME: Implement your code here */
465
 
        return WERR_NOT_SUPPORTED;
466
 
}
467
 
 
468
 
WERROR _dfs_SetInfo2(pipes_struct *p, NETDFS_Q_DFS_SETINFO2 *q_u, NETDFS_R_DFS_SETINFO2 *r_u)
469
 
{
470
 
        /* FIXME: Implement your code here */
471
 
        return WERR_NOT_SUPPORTED;
472
 
}
473