/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- pipe_enum_fn
- net_enum_pipes
- enum_file_fn
- net_enum_files
- get_share_type
- init_srv_share_info_0
- init_srv_share_info_1
- init_srv_share_info_2
- map_generic_share_sd_bits
- init_srv_share_info_501
- init_srv_share_info_502
- init_srv_share_info_1004
- init_srv_share_info_1005
- init_srv_share_info_1006
- init_srv_share_info_1007
- init_srv_share_info_1501
- is_hidden_share
- is_enumeration_allowed
- init_srv_share_info_ctr
- init_srv_sess_info_0
- sess_file_fn
- net_count_files
- init_srv_sess_info_1
- init_srv_conn_info_0
- init_srv_conn_info_1
- _srvsvc_NetFileEnum
- _srvsvc_NetSrvGetInfo
- _srvsvc_NetSrvSetInfo
- _srvsvc_NetConnEnum
- _srvsvc_NetSessEnum
- _srvsvc_NetSessDel
- _srvsvc_NetShareEnumAll
- _srvsvc_NetShareEnum
- _srvsvc_NetShareGetInfo
- valid_share_pathname
- _srvsvc_NetShareSetInfo
- _srvsvc_NetShareAdd
- _srvsvc_NetShareDel
- _srvsvc_NetShareDelSticky
- _srvsvc_NetRemoteTOD
- _srvsvc_NetGetFileSecurity
- _srvsvc_NetSetFileSecurity
- get_server_disk_count
- init_server_disk_enum
- next_server_disk_enum
- _srvsvc_NetDiskEnum
- _srvsvc_NetNameValidate
- enum_file_close_fn
- _srvsvc_NetFileClose
- _srvsvc_NetCharDevEnum
- _srvsvc_NetCharDevGetInfo
- _srvsvc_NetCharDevControl
- _srvsvc_NetCharDevQEnum
- _srvsvc_NetCharDevQGetInfo
- _srvsvc_NetCharDevQSetInfo
- _srvsvc_NetCharDevQPurge
- _srvsvc_NetCharDevQPurgeSelf
- _srvsvc_NetFileGetInfo
- _srvsvc_NetShareCheck
- _srvsvc_NetServerStatisticsGet
- _srvsvc_NetTransportAdd
- _srvsvc_NetTransportEnum
- _srvsvc_NetTransportDel
- _srvsvc_NetSetServiceBits
- _srvsvc_NetPathType
- _srvsvc_NetPathCanonicalize
- _srvsvc_NetPathCompare
- _srvsvc_NETRPRNAMECANONICALIZE
- _srvsvc_NetPRNameCompare
- _srvsvc_NetShareDelStart
- _srvsvc_NetShareDelCommit
- _srvsvc_NetServerTransportAddEx
- _srvsvc_NetServerSetServiceBitsEx
- _srvsvc_NETRDFSGETVERSION
- _srvsvc_NETRDFSCREATELOCALPARTITION
- _srvsvc_NETRDFSDELETELOCALPARTITION
- _srvsvc_NETRDFSSETLOCALVOLUMESTATE
- _srvsvc_NETRDFSSETSERVERINFO
- _srvsvc_NETRDFSCREATEEXITPOINT
- _srvsvc_NETRDFSDELETEEXITPOINT
- _srvsvc_NETRDFSMODIFYPREFIX
- _srvsvc_NETRDFSFIXLOCALVOLUME
- _srvsvc_NETRDFSMANAGERREPORTSITEINFO
- _srvsvc_NETRSERVERTRANSPORTDELEX
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
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 3 of the License, or
13 * (at your option) any later version.
14 *
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.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /* This is the implementation of the srvsvc pipe. */
25
26 #include "includes.h"
27
28 extern const struct generic_mapping file_generic_mapping;
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
32
33 #define MAX_SERVER_DISK_ENTRIES 15
34
35 /* Use for enumerating connections, pipes, & files */
36
37 struct file_enum_count {
38 TALLOC_CTX *ctx;
39 const char *username;
40 struct srvsvc_NetFileCtr3 *ctr3;
41 };
42
43 struct sess_file_count {
44 struct server_id pid;
45 uid_t uid;
46 int count;
47 };
48
49 /****************************************************************************
50 Count the entries belonging to a service in the connection db.
51 ****************************************************************************/
52
53 static int pipe_enum_fn( struct db_record *rec, void *p)
/* [<][>][^][v][top][bottom][index][help] */
54 {
55 struct pipe_open_rec prec;
56 struct file_enum_count *fenum = (struct file_enum_count *)p;
57 struct srvsvc_NetFileInfo3 *f;
58 int i = fenum->ctr3->count;
59 char *fullpath = NULL;
60 const char *username;
61
62 if (rec->value.dsize != sizeof(struct pipe_open_rec))
63 return 0;
64
65 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
66
67 if ( !process_exists(prec.pid) ) {
68 return 0;
69 }
70
71 username = uidtoname(prec.uid);
72
73 if ((fenum->username != NULL)
74 && !strequal(username, fenum->username)) {
75 return 0;
76 }
77
78 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
79 if (!fullpath) {
80 return 1;
81 }
82
83 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
84 struct srvsvc_NetFileInfo3, i+1);
85 if ( !f ) {
86 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
87 return 1;
88 }
89 fenum->ctr3->array = f;
90
91 fenum->ctr3->array[i].fid =
92 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
93 fenum->ctr3->array[i].permissions =
94 (FILE_READ_DATA|FILE_WRITE_DATA);
95 fenum->ctr3->array[i].num_locks = 0;
96 fenum->ctr3->array[i].path = fullpath;
97 fenum->ctr3->array[i].user = username;
98
99 fenum->ctr3->count++;
100
101 return 0;
102 }
103
104 /*******************************************************************
105 ********************************************************************/
106
107 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
/* [<][>][^][v][top][bottom][index][help] */
108 const char *username,
109 struct srvsvc_NetFileCtr3 **ctr3,
110 uint32_t resume )
111 {
112 struct file_enum_count fenum;
113
114 fenum.ctx = ctx;
115 fenum.username = username;
116 fenum.ctr3 = *ctr3;
117
118 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
119 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
120 "failed\n"));
121 return WERR_NOMEM;
122 }
123
124 *ctr3 = fenum.ctr3;
125
126 return WERR_OK;
127 }
128
129 /*******************************************************************
130 ********************************************************************/
131
132 static void enum_file_fn( const struct share_mode_entry *e,
/* [<][>][^][v][top][bottom][index][help] */
133 const char *sharepath, const char *fname,
134 void *private_data )
135 {
136 struct file_enum_count *fenum =
137 (struct file_enum_count *)private_data;
138
139 struct srvsvc_NetFileInfo3 *f;
140 int i = fenum->ctr3->count;
141 files_struct fsp;
142 struct byte_range_lock *brl;
143 int num_locks = 0;
144 char *fullpath = NULL;
145 uint32 permissions;
146 const char *username;
147
148 /* If the pid was not found delete the entry from connections.tdb */
149
150 if ( !process_exists(e->pid) ) {
151 return;
152 }
153
154 username = uidtoname(e->uid);
155
156 if ((fenum->username != NULL)
157 && !strequal(username, fenum->username)) {
158 return;
159 }
160
161 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
162 struct srvsvc_NetFileInfo3, i+1);
163 if ( !f ) {
164 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
165 return;
166 }
167 fenum->ctr3->array = f;
168
169 /* need to count the number of locks on a file */
170
171 ZERO_STRUCT( fsp );
172 fsp.file_id = e->id;
173
174 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
175 num_locks = brl->num_locks;
176 TALLOC_FREE(brl);
177 }
178
179 if ( strcmp( fname, "." ) == 0 ) {
180 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
181 } else {
182 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
183 sharepath, fname );
184 }
185 if (!fullpath) {
186 return;
187 }
188 string_replace( fullpath, '/', '\\' );
189
190 /* mask out create (what ever that is) */
191 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
192
193 /* now fill in the srvsvc_NetFileInfo3 struct */
194
195 fenum->ctr3->array[i].fid =
196 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
197 fenum->ctr3->array[i].permissions = permissions;
198 fenum->ctr3->array[i].num_locks = num_locks;
199 fenum->ctr3->array[i].path = fullpath;
200 fenum->ctr3->array[i].user = username;
201
202 fenum->ctr3->count++;
203 }
204
205 /*******************************************************************
206 ********************************************************************/
207
208 static WERROR net_enum_files(TALLOC_CTX *ctx,
/* [<][>][^][v][top][bottom][index][help] */
209 const char *username,
210 struct srvsvc_NetFileCtr3 **ctr3,
211 uint32_t resume)
212 {
213 struct file_enum_count f_enum_cnt;
214
215 f_enum_cnt.ctx = ctx;
216 f_enum_cnt.username = username;
217 f_enum_cnt.ctr3 = *ctr3;
218
219 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
220
221 *ctr3 = f_enum_cnt.ctr3;
222
223 return WERR_OK;
224 }
225
226 /*******************************************************************
227 Utility function to get the 'type' of a share from an snum.
228 ********************************************************************/
229 static uint32 get_share_type(int snum)
/* [<][>][^][v][top][bottom][index][help] */
230 {
231 /* work out the share type */
232 uint32 type = STYPE_DISKTREE;
233
234 if (lp_print_ok(snum))
235 type = STYPE_PRINTQ;
236 if (strequal(lp_fstype(snum), "IPC"))
237 type = STYPE_IPC;
238 if (lp_administrative_share(snum))
239 type |= STYPE_HIDDEN;
240
241 return type;
242 }
243
244 /*******************************************************************
245 Fill in a share info level 0 structure.
246 ********************************************************************/
247
248 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
249 {
250 r->name = lp_servicename(snum);
251 }
252
253 /*******************************************************************
254 Fill in a share info level 1 structure.
255 ********************************************************************/
256
257 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
258 {
259 char *net_name = lp_servicename(snum);
260 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
261
262 if (remark) {
263 remark = talloc_sub_advanced(
264 p->mem_ctx, lp_servicename(snum),
265 get_current_username(), lp_pathname(snum),
266 p->server_info->utok.uid, get_current_username(),
267 "", remark);
268 }
269
270 r->name = net_name;
271 r->type = get_share_type(snum);
272 r->comment = remark ? remark : "";
273 }
274
275 /*******************************************************************
276 Fill in a share info level 2 structure.
277 ********************************************************************/
278
279 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
280 {
281 char *remark = NULL;
282 char *path = NULL;
283 int max_connections = lp_max_connections(snum);
284 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
285 char *net_name = lp_servicename(snum);
286
287 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
288 if (remark) {
289 remark = talloc_sub_advanced(
290 p->mem_ctx, lp_servicename(snum),
291 get_current_username(), lp_pathname(snum),
292 p->server_info->utok.uid, get_current_username(),
293 "", remark);
294 }
295 path = talloc_asprintf(p->mem_ctx,
296 "C:%s", lp_pathname(snum));
297
298 if (path) {
299 /*
300 * Change / to \\ so that win2k will see it as a valid path.
301 * This was added to enable use of browsing in win2k add
302 * share dialog.
303 */
304
305 string_replace(path, '/', '\\');
306 }
307
308 r->name = net_name;
309 r->type = get_share_type(snum);
310 r->comment = remark ? remark : "";
311 r->permissions = 0;
312 r->max_users = max_uses;
313 r->current_users = count_current_connections(net_name, false);
314 r->path = path ? path : "";
315 r->password = "";
316 }
317
318 /*******************************************************************
319 Map any generic bits to file specific bits.
320 ********************************************************************/
321
322 static void map_generic_share_sd_bits(SEC_DESC *psd)
/* [<][>][^][v][top][bottom][index][help] */
323 {
324 int i;
325 SEC_ACL *ps_dacl = NULL;
326
327 if (!psd)
328 return;
329
330 ps_dacl = psd->dacl;
331 if (!ps_dacl)
332 return;
333
334 for (i = 0; i < ps_dacl->num_aces; i++) {
335 SEC_ACE *psa = &ps_dacl->aces[i];
336 uint32 orig_mask = psa->access_mask;
337
338 se_map_generic(&psa->access_mask, &file_generic_mapping);
339 psa->access_mask |= orig_mask;
340 }
341 }
342
343 /*******************************************************************
344 Fill in a share info level 501 structure.
345 ********************************************************************/
346
347 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
348 {
349 const char *net_name = lp_servicename(snum);
350 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
351
352 if (remark) {
353 remark = talloc_sub_advanced(
354 p->mem_ctx, lp_servicename(snum),
355 get_current_username(), lp_pathname(snum),
356 p->server_info->utok.uid, get_current_username(),
357 "", remark);
358 }
359
360 r->name = net_name;
361 r->type = get_share_type(snum);
362 r->comment = remark ? remark : "";
363 r->csc_policy = (lp_csc_policy(snum) << 4);
364 }
365
366 /*******************************************************************
367 Fill in a share info level 502 structure.
368 ********************************************************************/
369
370 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
371 {
372 const char *net_name = lp_servicename(snum);
373 char *path = NULL;
374 SEC_DESC *sd = NULL;
375 struct sec_desc_buf *sd_buf = NULL;
376 size_t sd_size = 0;
377 TALLOC_CTX *ctx = p->mem_ctx;
378 char *remark = talloc_strdup(ctx, lp_comment(snum));;
379
380 if (remark) {
381 remark = talloc_sub_advanced(
382 p->mem_ctx, lp_servicename(snum),
383 get_current_username(), lp_pathname(snum),
384 p->server_info->utok.uid, get_current_username(),
385 "", remark);
386 }
387 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
388 if (path) {
389 /*
390 * Change / to \\ so that win2k will see it as a valid path. This was added to
391 * enable use of browsing in win2k add share dialog.
392 */
393 string_replace(path, '/', '\\');
394 }
395
396 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
397
398 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
399
400 r->name = net_name;
401 r->type = get_share_type(snum);
402 r->comment = remark ? remark : "";
403 r->permissions = 0;
404 r->max_users = (uint32_t)-1;
405 r->current_users = 1; /* ??? */
406 r->path = path ? path : "";
407 r->password = "";
408 r->sd_buf = *sd_buf;
409 }
410
411 /***************************************************************************
412 Fill in a share info level 1004 structure.
413 ***************************************************************************/
414
415 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
416 {
417 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
418
419 if (remark) {
420 remark = talloc_sub_advanced(
421 p->mem_ctx, lp_servicename(snum),
422 get_current_username(), lp_pathname(snum),
423 p->server_info->utok.uid, get_current_username(),
424 "", remark);
425 }
426
427 r->comment = remark ? remark : "";
428 }
429
430 /***************************************************************************
431 Fill in a share info level 1005 structure.
432 ***************************************************************************/
433
434 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
435 {
436 uint32_t dfs_flags = 0;
437
438 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
439 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
440 }
441
442 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
443
444 r->dfs_flags = dfs_flags;
445 }
446
447 /***************************************************************************
448 Fill in a share info level 1006 structure.
449 ***************************************************************************/
450
451 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
452 {
453 r->max_users = (uint32_t)-1;
454 }
455
456 /***************************************************************************
457 Fill in a share info level 1007 structure.
458 ***************************************************************************/
459
460 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
461 {
462 r->flags = 0;
463 r->alternate_directory_name = "";
464 }
465
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
469
470 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
/* [<][>][^][v][top][bottom][index][help] */
471 {
472 SEC_DESC *sd;
473 size_t sd_size;
474 TALLOC_CTX *ctx = p->mem_ctx;
475
476 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
477
478 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
479 }
480
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
484
485 static bool is_hidden_share(int snum)
/* [<][>][^][v][top][bottom][index][help] */
486 {
487 const char *net_name = lp_servicename(snum);
488
489 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
490 }
491
492 /*******************************************************************
493 Verify user is allowed to view share, access based enumeration
494 ********************************************************************/
495 static bool is_enumeration_allowed(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
496 int snum)
497 {
498 if (!lp_access_based_share_enum(snum))
499 return true;
500
501 return share_access_check(p->server_info->ptok, lp_servicename(snum),
502 FILE_READ_DATA);
503 }
504
505 /*******************************************************************
506 Fill in a share info structure.
507 ********************************************************************/
508
509 static WERROR init_srv_share_info_ctr(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
510 struct srvsvc_NetShareInfoCtr *info_ctr,
511 uint32_t *resume_handle_p,
512 uint32_t *total_entries,
513 bool all_shares)
514 {
515 int num_entries = 0;
516 int alloc_entries = 0;
517 int num_services = 0;
518 int snum;
519 TALLOC_CTX *ctx = p->mem_ctx;
520 int i = 0;
521 int valid_share_count = 0;
522 bool *allowed = 0;
523 union srvsvc_NetShareCtr ctr;
524 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
525
526 DEBUG(5,("init_srv_share_info_ctr\n"));
527
528 /* Ensure all the usershares are loaded. */
529 become_root();
530 load_usershare_shares();
531 load_registry_shares();
532 num_services = lp_numservices();
533 unbecome_root();
534
535 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
536 W_ERROR_HAVE_NO_MEMORY(allowed);
537
538 /* Count the number of entries. */
539 for (snum = 0; snum < num_services; snum++) {
540 if (lp_browseable(snum) && lp_snum_ok(snum) &&
541 is_enumeration_allowed(p, snum) &&
542 (all_shares || !is_hidden_share(snum)) ) {
543 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
544 allowed[snum] = true;
545 num_entries++;
546 } else {
547 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
548 }
549 }
550
551 if (!num_entries || (resume_handle >= num_entries)) {
552 return WERR_OK;
553 }
554
555 /* Calculate alloc entries. */
556 alloc_entries = num_entries - resume_handle;
557 switch (info_ctr->level) {
558 case 0:
559 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
560 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
561
562 ctr.ctr0->count = alloc_entries;
563 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
564 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
565
566 for (snum = 0; snum < num_services; snum++) {
567 if (allowed[snum] &&
568 (resume_handle <= (i + valid_share_count++)) ) {
569 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
570 }
571 }
572
573 break;
574
575 case 1:
576 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
577 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
578
579 ctr.ctr1->count = alloc_entries;
580 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
581 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
582
583 for (snum = 0; snum < num_services; snum++) {
584 if (allowed[snum] &&
585 (resume_handle <= (i + valid_share_count++)) ) {
586 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
587 }
588 }
589
590 break;
591
592 case 2:
593 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
594 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
595
596 ctr.ctr2->count = alloc_entries;
597 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
598 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
599
600 for (snum = 0; snum < num_services; snum++) {
601 if (allowed[snum] &&
602 (resume_handle <= (i + valid_share_count++)) ) {
603 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
604 }
605 }
606
607 break;
608
609 case 501:
610 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
611 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
612
613 ctr.ctr501->count = alloc_entries;
614 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
615 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
616
617 for (snum = 0; snum < num_services; snum++) {
618 if (allowed[snum] &&
619 (resume_handle <= (i + valid_share_count++)) ) {
620 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
621 }
622 }
623
624 break;
625
626 case 502:
627 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
628 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
629
630 ctr.ctr502->count = alloc_entries;
631 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
632 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
633
634 for (snum = 0; snum < num_services; snum++) {
635 if (allowed[snum] &&
636 (resume_handle <= (i + valid_share_count++)) ) {
637 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
638 }
639 }
640
641 break;
642
643 case 1004:
644 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
646
647 ctr.ctr1004->count = alloc_entries;
648 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
649 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
650
651 for (snum = 0; snum < num_services; snum++) {
652 if (allowed[snum] &&
653 (resume_handle <= (i + valid_share_count++)) ) {
654 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
655 }
656 }
657
658 break;
659
660 case 1005:
661 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
663
664 ctr.ctr1005->count = alloc_entries;
665 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
666 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
667
668 for (snum = 0; snum < num_services; snum++) {
669 if (allowed[snum] &&
670 (resume_handle <= (i + valid_share_count++)) ) {
671 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
672 }
673 }
674
675 break;
676
677 case 1006:
678 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
680
681 ctr.ctr1006->count = alloc_entries;
682 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
683 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
684
685 for (snum = 0; snum < num_services; snum++) {
686 if (allowed[snum] &&
687 (resume_handle <= (i + valid_share_count++)) ) {
688 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
689 }
690 }
691
692 break;
693
694 case 1007:
695 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
696 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
697
698 ctr.ctr1007->count = alloc_entries;
699 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
700 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
701
702 for (snum = 0; snum < num_services; snum++) {
703 if (allowed[snum] &&
704 (resume_handle <= (i + valid_share_count++)) ) {
705 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
706 }
707 }
708
709 break;
710
711 case 1501:
712 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
713 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
714
715 ctr.ctr1501->count = alloc_entries;
716 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
717 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
718
719 for (snum = 0; snum < num_services; snum++) {
720 if (allowed[snum] &&
721 (resume_handle <= (i + valid_share_count++)) ) {
722 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
723 }
724 }
725
726 break;
727
728 default:
729 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
730 info_ctr->level));
731 return WERR_UNKNOWN_LEVEL;
732 }
733
734 *total_entries = alloc_entries;
735 if (resume_handle_p) {
736 if (all_shares) {
737 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
738 } else {
739 *resume_handle_p = num_entries;
740 }
741 }
742
743 info_ctr->ctr = ctr;
744
745 return WERR_OK;
746 }
747
748 /*******************************************************************
749 fill in a sess info level 0 structure.
750 ********************************************************************/
751
752 static WERROR init_srv_sess_info_0(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
753 struct srvsvc_NetSessCtr0 *ctr0,
754 uint32_t *resume_handle_p,
755 uint32_t *total_entries)
756 {
757 struct sessionid *session_list;
758 uint32_t num_entries = 0;
759 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
760 *total_entries = list_sessions(p->mem_ctx, &session_list);
761
762 DEBUG(5,("init_srv_sess_info_0\n"));
763
764 if (ctr0 == NULL) {
765 if (resume_handle_p) {
766 *resume_handle_p = 0;
767 }
768 return WERR_OK;
769 }
770
771 for (; resume_handle < *total_entries; resume_handle++) {
772
773 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
774 ctr0->array,
775 struct srvsvc_NetSessInfo0,
776 num_entries+1);
777 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
778
779 ctr0->array[num_entries].client =
780 session_list[resume_handle].remote_machine;
781
782 num_entries++;
783 }
784
785 ctr0->count = num_entries;
786
787 if (resume_handle_p) {
788 if (*resume_handle_p >= *total_entries) {
789 *resume_handle_p = 0;
790 } else {
791 *resume_handle_p = resume_handle;
792 }
793 }
794
795 return WERR_OK;
796 }
797
798 /*******************************************************************
799 ********************************************************************/
800
801 static void sess_file_fn( const struct share_mode_entry *e,
/* [<][>][^][v][top][bottom][index][help] */
802 const char *sharepath, const char *fname,
803 void *data )
804 {
805 struct sess_file_count *sess = (struct sess_file_count *)data;
806
807 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
808 sess->count++;
809 }
810
811 return;
812 }
813
814 /*******************************************************************
815 ********************************************************************/
816
817 static int net_count_files( uid_t uid, struct server_id pid )
/* [<][>][^][v][top][bottom][index][help] */
818 {
819 struct sess_file_count s_file_cnt;
820
821 s_file_cnt.count = 0;
822 s_file_cnt.uid = uid;
823 s_file_cnt.pid = pid;
824
825 share_mode_forall( sess_file_fn, &s_file_cnt );
826
827 return s_file_cnt.count;
828 }
829
830 /*******************************************************************
831 fill in a sess info level 1 structure.
832 ********************************************************************/
833
834 static WERROR init_srv_sess_info_1(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
835 struct srvsvc_NetSessCtr1 *ctr1,
836 uint32_t *resume_handle_p,
837 uint32_t *total_entries)
838 {
839 struct sessionid *session_list;
840 uint32_t num_entries = 0;
841 time_t now = time(NULL);
842 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
843
844 ZERO_STRUCTP(ctr1);
845
846 if (ctr1 == NULL) {
847 if (resume_handle_p) {
848 *resume_handle_p = 0;
849 }
850 return WERR_OK;
851 }
852
853 *total_entries = list_sessions(p->mem_ctx, &session_list);
854
855 for (; resume_handle < *total_entries; resume_handle++) {
856 uint32 num_files;
857 uint32 connect_time;
858 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
859 bool guest;
860
861 if ( !pw ) {
862 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
863 session_list[resume_handle].username));
864 continue;
865 }
866
867 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
868 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
869 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
870
871 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
872 ctr1->array,
873 struct srvsvc_NetSessInfo1,
874 num_entries+1);
875 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
876
877 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
878 ctr1->array[num_entries].user = session_list[resume_handle].username;
879 ctr1->array[num_entries].num_open = num_files;
880 ctr1->array[num_entries].time = connect_time;
881 ctr1->array[num_entries].idle_time = 0;
882 ctr1->array[num_entries].user_flags = guest;
883
884 num_entries++;
885 }
886
887 ctr1->count = num_entries;
888
889 if (resume_handle_p) {
890 if (*resume_handle_p >= *total_entries) {
891 *resume_handle_p = 0;
892 } else {
893 *resume_handle_p = resume_handle;
894 }
895 }
896
897 return WERR_OK;
898 }
899
900 /*******************************************************************
901 fill in a conn info level 0 structure.
902 ********************************************************************/
903
904 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
/* [<][>][^][v][top][bottom][index][help] */
905 uint32_t *resume_handle_p,
906 uint32_t *total_entries)
907 {
908 uint32_t num_entries = 0;
909 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
910
911 DEBUG(5,("init_srv_conn_info_0\n"));
912
913 if (ctr0 == NULL) {
914 if (resume_handle_p) {
915 *resume_handle_p = 0;
916 }
917 return WERR_OK;
918 }
919
920 *total_entries = 1;
921
922 ZERO_STRUCTP(ctr0);
923
924 for (; resume_handle < *total_entries; resume_handle++) {
925
926 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
927 ctr0->array,
928 struct srvsvc_NetConnInfo0,
929 num_entries+1);
930 if (!ctr0->array) {
931 return WERR_NOMEM;
932 }
933
934 ctr0->array[num_entries].conn_id = *total_entries;
935
936 /* move on to creating next connection */
937 num_entries++;
938 }
939
940 ctr0->count = num_entries;
941 *total_entries = num_entries;
942
943 if (resume_handle_p) {
944 if (*resume_handle_p >= *total_entries) {
945 *resume_handle_p = 0;
946 } else {
947 *resume_handle_p = resume_handle;
948 }
949 }
950
951 return WERR_OK;
952 }
953
954 /*******************************************************************
955 fill in a conn info level 1 structure.
956 ********************************************************************/
957
958 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
/* [<][>][^][v][top][bottom][index][help] */
959 uint32_t *resume_handle_p,
960 uint32_t *total_entries)
961 {
962 uint32_t num_entries = 0;
963 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
964
965 DEBUG(5,("init_srv_conn_info_1\n"));
966
967 if (ctr1 == NULL) {
968 if (resume_handle_p) {
969 *resume_handle_p = 0;
970 }
971 return WERR_OK;
972 }
973
974 *total_entries = 1;
975
976 ZERO_STRUCTP(ctr1);
977
978 for (; resume_handle < *total_entries; resume_handle++) {
979
980 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
981 ctr1->array,
982 struct srvsvc_NetConnInfo1,
983 num_entries+1);
984 if (!ctr1->array) {
985 return WERR_NOMEM;
986 }
987
988 ctr1->array[num_entries].conn_id = *total_entries;
989 ctr1->array[num_entries].conn_type = 0x3;
990 ctr1->array[num_entries].num_open = 1;
991 ctr1->array[num_entries].num_users = 1;
992 ctr1->array[num_entries].conn_time = 3;
993 ctr1->array[num_entries].user = "dummy_user";
994 ctr1->array[num_entries].share = "IPC$";
995
996 /* move on to creating next connection */
997 num_entries++;
998 }
999
1000 ctr1->count = num_entries;
1001 *total_entries = num_entries;
1002
1003 if (resume_handle_p) {
1004 if (*resume_handle_p >= *total_entries) {
1005 *resume_handle_p = 0;
1006 } else {
1007 *resume_handle_p = resume_handle;
1008 }
1009 }
1010
1011 return WERR_OK;
1012 }
1013
1014 /*******************************************************************
1015 _srvsvc_NetFileEnum
1016 *******************************************************************/
1017
1018 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1019 struct srvsvc_NetFileEnum *r)
1020 {
1021 TALLOC_CTX *ctx = NULL;
1022 struct srvsvc_NetFileCtr3 *ctr3;
1023 uint32_t resume_hnd = 0;
1024 WERROR werr;
1025
1026 switch (r->in.info_ctr->level) {
1027 case 3:
1028 break;
1029 default:
1030 return WERR_UNKNOWN_LEVEL;
1031 }
1032
1033 ctx = talloc_tos();
1034 ctr3 = r->in.info_ctr->ctr.ctr3;
1035 if (!ctr3) {
1036 werr = WERR_INVALID_PARAM;
1037 goto done;
1038 }
1039
1040 /* TODO -- Windows enumerates
1041 (b) active pipes
1042 (c) open directories and files */
1043
1044 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1045 if (!W_ERROR_IS_OK(werr)) {
1046 goto done;
1047 }
1048
1049 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1050 if (!W_ERROR_IS_OK(werr)) {
1051 goto done;
1052 }
1053
1054 *r->out.totalentries = ctr3->count;
1055 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1056 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1057
1058 werr = WERR_OK;
1059
1060 done:
1061 return werr;
1062 }
1063
1064 /*******************************************************************
1065 _srvsvc_NetSrvGetInfo
1066 ********************************************************************/
1067
1068 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1069 struct srvsvc_NetSrvGetInfo *r)
1070 {
1071 WERROR status = WERR_OK;
1072
1073 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1074
1075 if (!pipe_access_check(p)) {
1076 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1077 return WERR_ACCESS_DENIED;
1078 }
1079
1080 switch (r->in.level) {
1081
1082 /* Technically level 102 should only be available to
1083 Administrators but there isn't anything super-secret
1084 here, as most of it is made up. */
1085
1086 case 102: {
1087 struct srvsvc_NetSrvInfo102 *info102;
1088
1089 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1090 if (!info102) {
1091 return WERR_NOMEM;
1092 }
1093
1094 info102->platform_id = PLATFORM_ID_NT;
1095 info102->server_name = global_myname();
1096 info102->version_major = lp_major_announce_version();
1097 info102->version_minor = lp_minor_announce_version();
1098 info102->server_type = lp_default_server_announce();
1099 info102->comment = string_truncate(lp_serverstring(),
1100 MAX_SERVER_STRING_LENGTH);
1101 info102->users = 0xffffffff;
1102 info102->disc = 0xf;
1103 info102->hidden = 0;
1104 info102->announce = 240;
1105 info102->anndelta = 3000;
1106 info102->licenses = 100000;
1107 info102->userpath = "C:\\";
1108
1109 r->out.info->info102 = info102;
1110 break;
1111 }
1112 case 101: {
1113 struct srvsvc_NetSrvInfo101 *info101;
1114
1115 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1116 if (!info101) {
1117 return WERR_NOMEM;
1118 }
1119
1120 info101->platform_id = PLATFORM_ID_NT;
1121 info101->server_name = global_myname();
1122 info101->version_major = lp_major_announce_version();
1123 info101->version_minor = lp_minor_announce_version();
1124 info101->server_type = lp_default_server_announce();
1125 info101->comment = string_truncate(lp_serverstring(),
1126 MAX_SERVER_STRING_LENGTH);
1127
1128 r->out.info->info101 = info101;
1129 break;
1130 }
1131 case 100: {
1132 struct srvsvc_NetSrvInfo100 *info100;
1133
1134 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1135 if (!info100) {
1136 return WERR_NOMEM;
1137 }
1138
1139 info100->platform_id = PLATFORM_ID_NT;
1140 info100->server_name = global_myname();
1141
1142 r->out.info->info100 = info100;
1143
1144 break;
1145 }
1146 default:
1147 status = WERR_UNKNOWN_LEVEL;
1148 break;
1149 }
1150
1151 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1152
1153 return status;
1154 }
1155
1156 /*******************************************************************
1157 _srvsvc_NetSrvSetInfo
1158 ********************************************************************/
1159
1160 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1161 struct srvsvc_NetSrvSetInfo *r)
1162 {
1163 WERROR status = WERR_OK;
1164
1165 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1166
1167 /* Set up the net server set info structure. */
1168
1169 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1170
1171 return status;
1172 }
1173
1174 /*******************************************************************
1175 _srvsvc_NetConnEnum
1176 ********************************************************************/
1177
1178 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1179 struct srvsvc_NetConnEnum *r)
1180 {
1181 WERROR werr;
1182
1183 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1184
1185 switch (r->in.info_ctr->level) {
1186 case 0:
1187 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1188 r->in.resume_handle,
1189 r->out.totalentries);
1190 break;
1191 case 1:
1192 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1193 r->in.resume_handle,
1194 r->out.totalentries);
1195 break;
1196 default:
1197 return WERR_UNKNOWN_LEVEL;
1198 }
1199
1200 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1201
1202 return werr;
1203 }
1204
1205 /*******************************************************************
1206 _srvsvc_NetSessEnum
1207 ********************************************************************/
1208
1209 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1210 struct srvsvc_NetSessEnum *r)
1211 {
1212 WERROR werr;
1213
1214 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1215
1216 switch (r->in.info_ctr->level) {
1217 case 0:
1218 werr = init_srv_sess_info_0(p,
1219 r->in.info_ctr->ctr.ctr0,
1220 r->in.resume_handle,
1221 r->out.totalentries);
1222 break;
1223 case 1:
1224 werr = init_srv_sess_info_1(p,
1225 r->in.info_ctr->ctr.ctr1,
1226 r->in.resume_handle,
1227 r->out.totalentries);
1228 break;
1229 default:
1230 return WERR_UNKNOWN_LEVEL;
1231 }
1232
1233 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1234
1235 return werr;
1236 }
1237
1238 /*******************************************************************
1239 _srvsvc_NetSessDel
1240 ********************************************************************/
1241
1242 WERROR _srvsvc_NetSessDel(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1243 struct srvsvc_NetSessDel *r)
1244 {
1245 struct sessionid *session_list;
1246 int num_sessions, snum;
1247 const char *username;
1248 const char *machine;
1249 bool not_root = False;
1250 WERROR werr;
1251
1252 username = r->in.user;
1253 machine = r->in.client;
1254
1255 /* strip leading backslashes if any */
1256 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1257 machine += 2;
1258 }
1259
1260 num_sessions = list_sessions(p->mem_ctx, &session_list);
1261
1262 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1263
1264 werr = WERR_ACCESS_DENIED;
1265
1266 /* fail out now if you are not root or not a domain admin */
1267
1268 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1269 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1270 DOMAIN_GROUP_RID_ADMINS))) {
1271
1272 goto done;
1273 }
1274
1275 for (snum = 0; snum < num_sessions; snum++) {
1276
1277 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1278 strequal(session_list[snum].remote_machine, machine)) {
1279
1280 NTSTATUS ntstat;
1281
1282 if (p->server_info->utok.uid != sec_initial_uid()) {
1283 not_root = True;
1284 become_root();
1285 }
1286
1287 ntstat = messaging_send(smbd_messaging_context(),
1288 session_list[snum].pid,
1289 MSG_SHUTDOWN, &data_blob_null);
1290
1291 if (NT_STATUS_IS_OK(ntstat))
1292 werr = WERR_OK;
1293
1294 if (not_root)
1295 unbecome_root();
1296 }
1297 }
1298
1299 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1300
1301 done:
1302
1303 return werr;
1304 }
1305
1306 /*******************************************************************
1307 _srvsvc_NetShareEnumAll
1308 ********************************************************************/
1309
1310 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1311 struct srvsvc_NetShareEnumAll *r)
1312 {
1313 WERROR werr;
1314
1315 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1316
1317 if (!pipe_access_check(p)) {
1318 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1319 return WERR_ACCESS_DENIED;
1320 }
1321
1322 /* Create the list of shares for the response. */
1323 werr = init_srv_share_info_ctr(p,
1324 r->in.info_ctr,
1325 r->in.resume_handle,
1326 r->out.totalentries,
1327 true);
1328
1329 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1330
1331 return werr;
1332 }
1333
1334 /*******************************************************************
1335 _srvsvc_NetShareEnum
1336 ********************************************************************/
1337
1338 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1339 struct srvsvc_NetShareEnum *r)
1340 {
1341 WERROR werr;
1342
1343 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1344
1345 if (!pipe_access_check(p)) {
1346 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1347 return WERR_ACCESS_DENIED;
1348 }
1349
1350 /* Create the list of shares for the response. */
1351 werr = init_srv_share_info_ctr(p,
1352 r->in.info_ctr,
1353 r->in.resume_handle,
1354 r->out.totalentries,
1355 false);
1356
1357 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1358
1359 return werr;
1360 }
1361
1362 /*******************************************************************
1363 _srvsvc_NetShareGetInfo
1364 ********************************************************************/
1365
1366 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1367 struct srvsvc_NetShareGetInfo *r)
1368 {
1369 WERROR status = WERR_OK;
1370 fstring share_name;
1371 int snum;
1372 union srvsvc_NetShareInfo *info = r->out.info;
1373
1374 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1375
1376 fstrcpy(share_name, r->in.share_name);
1377
1378 snum = find_service(share_name);
1379 if (snum < 0) {
1380 return WERR_INVALID_NAME;
1381 }
1382
1383 switch (r->in.level) {
1384 case 0:
1385 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1386 W_ERROR_HAVE_NO_MEMORY(info->info0);
1387 init_srv_share_info_0(p, info->info0, snum);
1388 break;
1389 case 1:
1390 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1391 W_ERROR_HAVE_NO_MEMORY(info->info1);
1392 init_srv_share_info_1(p, info->info1, snum);
1393 break;
1394 case 2:
1395 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1396 W_ERROR_HAVE_NO_MEMORY(info->info2);
1397 init_srv_share_info_2(p, info->info2, snum);
1398 break;
1399 case 501:
1400 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1401 W_ERROR_HAVE_NO_MEMORY(info->info501);
1402 init_srv_share_info_501(p, info->info501, snum);
1403 break;
1404 case 502:
1405 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1406 W_ERROR_HAVE_NO_MEMORY(info->info502);
1407 init_srv_share_info_502(p, info->info502, snum);
1408 break;
1409 case 1004:
1410 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1411 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1412 init_srv_share_info_1004(p, info->info1004, snum);
1413 break;
1414 case 1005:
1415 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1416 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1417 init_srv_share_info_1005(p, info->info1005, snum);
1418 break;
1419 case 1006:
1420 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1421 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1422 init_srv_share_info_1006(p, info->info1006, snum);
1423 break;
1424 case 1007:
1425 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1426 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1427 init_srv_share_info_1007(p, info->info1007, snum);
1428 break;
1429 case 1501:
1430 init_srv_share_info_1501(p, info->info1501, snum);
1431 break;
1432 default:
1433 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1434 r->in.level));
1435 status = WERR_UNKNOWN_LEVEL;
1436 break;
1437 }
1438
1439 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1440
1441 return status;
1442 }
1443
1444 /*******************************************************************
1445 Check a given DOS pathname is valid for a share.
1446 ********************************************************************/
1447
1448 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
/* [<][>][^][v][top][bottom][index][help] */
1449 {
1450 char *ptr = NULL;
1451
1452 if (!dos_pathname) {
1453 return NULL;
1454 }
1455
1456 ptr = talloc_strdup(ctx, dos_pathname);
1457 if (!ptr) {
1458 return NULL;
1459 }
1460 /* Convert any '\' paths to '/' */
1461 unix_format(ptr);
1462 ptr = unix_clean_name(ctx, ptr);
1463 if (!ptr) {
1464 return NULL;
1465 }
1466
1467 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1468 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1469 ptr += 2;
1470
1471 /* Only absolute paths allowed. */
1472 if (*ptr != '/')
1473 return NULL;
1474
1475 return ptr;
1476 }
1477
1478 /*******************************************************************
1479 _srvsvc_NetShareSetInfo. Modify share details.
1480 ********************************************************************/
1481
1482 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1483 struct srvsvc_NetShareSetInfo *r)
1484 {
1485 char *command = NULL;
1486 char *share_name = NULL;
1487 char *comment = NULL;
1488 const char *pathname = NULL;
1489 int type;
1490 int snum;
1491 int ret;
1492 char *path = NULL;
1493 SEC_DESC *psd = NULL;
1494 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1495 bool is_disk_op = False;
1496 int max_connections = 0;
1497 TALLOC_CTX *ctx = p->mem_ctx;
1498 union srvsvc_NetShareInfo *info = r->in.info;
1499
1500 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1501
1502 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1503 if (!share_name) {
1504 return WERR_NOMEM;
1505 }
1506
1507 if (r->out.parm_error) {
1508 *r->out.parm_error = 0;
1509 }
1510
1511 if ( strequal(share_name,"IPC$")
1512 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1513 || strequal(share_name,"global") )
1514 {
1515 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1516 "modified by a remote user.\n",
1517 share_name ));
1518 return WERR_ACCESS_DENIED;
1519 }
1520
1521 snum = find_service(share_name);
1522
1523 /* Does this share exist ? */
1524 if (snum < 0)
1525 return WERR_NET_NAME_NOT_FOUND;
1526
1527 /* No change to printer shares. */
1528 if (lp_print_ok(snum))
1529 return WERR_ACCESS_DENIED;
1530
1531 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1532
1533 /* fail out now if you are not root and not a disk op */
1534
1535 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1536 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1537 "SeDiskOperatorPrivilege privilege needed to modify "
1538 "share %s\n",
1539 (unsigned int)p->server_info->utok.uid,
1540 share_name ));
1541 return WERR_ACCESS_DENIED;
1542 }
1543
1544 switch (r->in.level) {
1545 case 1:
1546 pathname = talloc_strdup(ctx, lp_pathname(snum));
1547 comment = talloc_strdup(ctx, info->info1->comment);
1548 type = info->info1->type;
1549 psd = NULL;
1550 break;
1551 case 2:
1552 comment = talloc_strdup(ctx, info->info2->comment);
1553 pathname = info->info2->path;
1554 type = info->info2->type;
1555 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1556 0 : info->info2->max_users;
1557 psd = NULL;
1558 break;
1559 #if 0
1560 /* not supported on set but here for completeness */
1561 case 501:
1562 comment = talloc_strdup(ctx, info->info501->comment);
1563 type = info->info501->type;
1564 psd = NULL;
1565 break;
1566 #endif
1567 case 502:
1568 comment = talloc_strdup(ctx, info->info502->comment);
1569 pathname = info->info502->path;
1570 type = info->info502->type;
1571 psd = info->info502->sd_buf.sd;
1572 map_generic_share_sd_bits(psd);
1573 break;
1574 case 1004:
1575 pathname = talloc_strdup(ctx, lp_pathname(snum));
1576 comment = talloc_strdup(ctx, info->info1004->comment);
1577 type = STYPE_DISKTREE;
1578 break;
1579 case 1005:
1580 /* XP re-sets the csc policy even if it wasn't changed by the
1581 user, so we must compare it to see if it's what is set in
1582 smb.conf, so that we can contine other ops like setting
1583 ACLs on a share */
1584 if (((info->info1005->dfs_flags &
1585 SHARE_1005_CSC_POLICY_MASK) >>
1586 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1587 return WERR_OK;
1588 else {
1589 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1590 return WERR_ACCESS_DENIED;
1591 }
1592 case 1006:
1593 case 1007:
1594 return WERR_ACCESS_DENIED;
1595 case 1501:
1596 pathname = talloc_strdup(ctx, lp_pathname(snum));
1597 comment = talloc_strdup(ctx, lp_comment(snum));
1598 psd = info->info1501->sd;
1599 map_generic_share_sd_bits(psd);
1600 type = STYPE_DISKTREE;
1601 break;
1602 default:
1603 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1604 r->in.level));
1605 return WERR_UNKNOWN_LEVEL;
1606 }
1607
1608 /* We can only modify disk shares. */
1609 if (type != STYPE_DISKTREE) {
1610 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1611 "disk share\n",
1612 share_name ));
1613 return WERR_ACCESS_DENIED;
1614 }
1615
1616 if (comment == NULL) {
1617 return WERR_NOMEM;
1618 }
1619
1620 /* Check if the pathname is valid. */
1621 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1622 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1623 pathname ));
1624 return WERR_OBJECT_PATH_INVALID;
1625 }
1626
1627 /* Ensure share name, pathname and comment don't contain '"' characters. */
1628 string_replace(share_name, '"', ' ');
1629 string_replace(path, '"', ' ');
1630 string_replace(comment, '"', ' ');
1631
1632 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1633 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1634
1635 /* Only call modify function if something changed. */
1636
1637 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1638 || (lp_max_connections(snum) != max_connections)) {
1639 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1640 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1641 return WERR_ACCESS_DENIED;
1642 }
1643
1644 command = talloc_asprintf(p->mem_ctx,
1645 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1646 lp_change_share_cmd(),
1647 get_dyn_CONFIGFILE(),
1648 share_name,
1649 path,
1650 comment ? comment : "",
1651 max_connections);
1652 if (!command) {
1653 return WERR_NOMEM;
1654 }
1655
1656 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1657
1658 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1659
1660 if (is_disk_op)
1661 become_root();
1662
1663 if ( (ret = smbrun(command, NULL)) == 0 ) {
1664 /* Tell everyone we updated smb.conf. */
1665 message_send_all(smbd_messaging_context(),
1666 MSG_SMB_CONF_UPDATED, NULL, 0,
1667 NULL);
1668 }
1669
1670 if ( is_disk_op )
1671 unbecome_root();
1672
1673 /********* END SeDiskOperatorPrivilege BLOCK *********/
1674
1675 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1676 command, ret ));
1677
1678 TALLOC_FREE(command);
1679
1680 if ( ret != 0 )
1681 return WERR_ACCESS_DENIED;
1682 } else {
1683 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1684 share_name ));
1685 }
1686
1687 /* Replace SD if changed. */
1688 if (psd) {
1689 SEC_DESC *old_sd;
1690 size_t sd_size;
1691
1692 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1693
1694 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1695 if (!set_share_security(share_name, psd))
1696 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1697 share_name ));
1698 }
1699 }
1700
1701 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1702
1703 return WERR_OK;
1704 }
1705
1706 /*******************************************************************
1707 _srvsvc_NetShareAdd.
1708 Call 'add_share_command "sharename" "pathname"
1709 "comment" "max connections = "
1710 ********************************************************************/
1711
1712 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1713 struct srvsvc_NetShareAdd *r)
1714 {
1715 char *command = NULL;
1716 char *share_name = NULL;
1717 char *comment = NULL;
1718 char *pathname = NULL;
1719 int type;
1720 int snum;
1721 int ret;
1722 char *path;
1723 SEC_DESC *psd = NULL;
1724 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1725 bool is_disk_op;
1726 int max_connections = 0;
1727 TALLOC_CTX *ctx = p->mem_ctx;
1728
1729 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1730
1731 if (r->out.parm_error) {
1732 *r->out.parm_error = 0;
1733 }
1734
1735 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1736
1737 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1738 return WERR_ACCESS_DENIED;
1739
1740 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1741 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1742 return WERR_ACCESS_DENIED;
1743 }
1744
1745 switch (r->in.level) {
1746 case 0:
1747 /* No path. Not enough info in a level 0 to do anything. */
1748 return WERR_ACCESS_DENIED;
1749 case 1:
1750 /* Not enough info in a level 1 to do anything. */
1751 return WERR_ACCESS_DENIED;
1752 case 2:
1753 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1754 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1755 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1756 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1757 0 : r->in.info->info2->max_users;
1758 type = r->in.info->info2->type;
1759 break;
1760 case 501:
1761 /* No path. Not enough info in a level 501 to do anything. */
1762 return WERR_ACCESS_DENIED;
1763 case 502:
1764 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1765 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1766 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1767 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1768 0 : r->in.info->info502->max_users;
1769 type = r->in.info->info502->type;
1770 psd = r->in.info->info502->sd_buf.sd;
1771 map_generic_share_sd_bits(psd);
1772 break;
1773
1774 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1775
1776 case 1004:
1777 case 1005:
1778 case 1006:
1779 case 1007:
1780 return WERR_ACCESS_DENIED;
1781 case 1501:
1782 /* DFS only level. */
1783 return WERR_ACCESS_DENIED;
1784 default:
1785 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1786 r->in.level));
1787 return WERR_UNKNOWN_LEVEL;
1788 }
1789
1790 /* check for invalid share names */
1791
1792 if (!share_name || !validate_net_name(share_name,
1793 INVALID_SHARENAME_CHARS,
1794 strlen(share_name))) {
1795 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1796 share_name ? share_name : ""));
1797 return WERR_INVALID_NAME;
1798 }
1799
1800 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1801 || (lp_enable_asu_support() &&
1802 strequal(share_name,"ADMIN$"))) {
1803 return WERR_ACCESS_DENIED;
1804 }
1805
1806 snum = find_service(share_name);
1807
1808 /* Share already exists. */
1809 if (snum >= 0) {
1810 return WERR_FILE_EXISTS;
1811 }
1812
1813 /* We can only add disk shares. */
1814 if (type != STYPE_DISKTREE) {
1815 return WERR_ACCESS_DENIED;
1816 }
1817
1818 /* Check if the pathname is valid. */
1819 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1820 return WERR_OBJECT_PATH_INVALID;
1821 }
1822
1823 /* Ensure share name, pathname and comment don't contain '"' characters. */
1824 string_replace(share_name, '"', ' ');
1825 string_replace(path, '"', ' ');
1826 if (comment) {
1827 string_replace(comment, '"', ' ');
1828 }
1829
1830 command = talloc_asprintf(ctx,
1831 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1832 lp_add_share_cmd(),
1833 get_dyn_CONFIGFILE(),
1834 share_name,
1835 path,
1836 comment ? comment : "",
1837 max_connections);
1838 if (!command) {
1839 return WERR_NOMEM;
1840 }
1841
1842 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1843
1844 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1845
1846 if ( is_disk_op )
1847 become_root();
1848
1849 /* FIXME: use libnetconf here - gd */
1850
1851 if ( (ret = smbrun(command, NULL)) == 0 ) {
1852 /* Tell everyone we updated smb.conf. */
1853 message_send_all(smbd_messaging_context(),
1854 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1855 }
1856
1857 if ( is_disk_op )
1858 unbecome_root();
1859
1860 /********* END SeDiskOperatorPrivilege BLOCK *********/
1861
1862 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1863 command, ret ));
1864
1865 TALLOC_FREE(command);
1866
1867 if ( ret != 0 )
1868 return WERR_ACCESS_DENIED;
1869
1870 if (psd) {
1871 if (!set_share_security(share_name, psd)) {
1872 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1873 share_name ));
1874 }
1875 }
1876
1877 /*
1878 * We don't call reload_services() here, the message will
1879 * cause this to be done before the next packet is read
1880 * from the client. JRA.
1881 */
1882
1883 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1884
1885 return WERR_OK;
1886 }
1887
1888 /*******************************************************************
1889 _srvsvc_NetShareDel
1890 Call "delete share command" with the share name as
1891 a parameter.
1892 ********************************************************************/
1893
1894 WERROR _srvsvc_NetShareDel(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1895 struct srvsvc_NetShareDel *r)
1896 {
1897 char *command = NULL;
1898 char *share_name = NULL;
1899 int ret;
1900 int snum;
1901 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1902 bool is_disk_op;
1903 struct share_params *params;
1904 TALLOC_CTX *ctx = p->mem_ctx;
1905
1906 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1907
1908 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1909 if (!share_name) {
1910 return WERR_NET_NAME_NOT_FOUND;
1911 }
1912 if ( strequal(share_name,"IPC$")
1913 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1914 || strequal(share_name,"global") )
1915 {
1916 return WERR_ACCESS_DENIED;
1917 }
1918
1919 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1920 return WERR_NO_SUCH_SHARE;
1921 }
1922
1923 snum = find_service(share_name);
1924
1925 /* No change to printer shares. */
1926 if (lp_print_ok(snum))
1927 return WERR_ACCESS_DENIED;
1928
1929 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1930
1931 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1932 return WERR_ACCESS_DENIED;
1933
1934 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1935 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1936 return WERR_ACCESS_DENIED;
1937 }
1938
1939 command = talloc_asprintf(ctx,
1940 "%s \"%s\" \"%s\"",
1941 lp_delete_share_cmd(),
1942 get_dyn_CONFIGFILE(),
1943 lp_servicename(snum));
1944 if (!command) {
1945 return WERR_NOMEM;
1946 }
1947
1948 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1949
1950 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1951
1952 if ( is_disk_op )
1953 become_root();
1954
1955 if ( (ret = smbrun(command, NULL)) == 0 ) {
1956 /* Tell everyone we updated smb.conf. */
1957 message_send_all(smbd_messaging_context(),
1958 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1959 }
1960
1961 if ( is_disk_op )
1962 unbecome_root();
1963
1964 /********* END SeDiskOperatorPrivilege BLOCK *********/
1965
1966 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1967
1968 if ( ret != 0 )
1969 return WERR_ACCESS_DENIED;
1970
1971 /* Delete the SD in the database. */
1972 delete_share_security(lp_servicename(params->service));
1973
1974 lp_killservice(params->service);
1975
1976 return WERR_OK;
1977 }
1978
1979 /*******************************************************************
1980 _srvsvc_NetShareDelSticky
1981 ********************************************************************/
1982
1983 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
1984 struct srvsvc_NetShareDelSticky *r)
1985 {
1986 struct srvsvc_NetShareDel q;
1987
1988 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1989
1990 q.in.server_unc = r->in.server_unc;
1991 q.in.share_name = r->in.share_name;
1992 q.in.reserved = r->in.reserved;
1993
1994 return _srvsvc_NetShareDel(p, &q);
1995 }
1996
1997 /*******************************************************************
1998 _srvsvc_NetRemoteTOD
1999 ********************************************************************/
2000
2001 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
2002 struct srvsvc_NetRemoteTOD *r)
2003 {
2004 struct srvsvc_NetRemoteTODInfo *tod;
2005 struct tm *t;
2006 time_t unixdate = time(NULL);
2007
2008 /* We do this call first as if we do it *after* the gmtime call
2009 it overwrites the pointed-to values. JRA */
2010
2011 uint32 zone = get_time_zone(unixdate)/60;
2012
2013 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2014
2015 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2016 return WERR_NOMEM;
2017
2018 *r->out.info = tod;
2019
2020 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2021
2022 t = gmtime(&unixdate);
2023
2024 /* set up the */
2025 tod->elapsed = unixdate;
2026 tod->msecs = 0;
2027 tod->hours = t->tm_hour;
2028 tod->mins = t->tm_min;
2029 tod->secs = t->tm_sec;
2030 tod->hunds = 0;
2031 tod->timezone = zone;
2032 tod->tinterval = 10000;
2033 tod->day = t->tm_mday;
2034 tod->month = t->tm_mon + 1;
2035 tod->year = 1900+t->tm_year;
2036 tod->weekday = t->tm_wday;
2037
2038 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2039
2040 return WERR_OK;
2041 }
2042
2043 /***********************************************************************************
2044 _srvsvc_NetGetFileSecurity
2045 Win9x NT tools get security descriptor.
2046 ***********************************************************************************/
2047
2048 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
2049 struct srvsvc_NetGetFileSecurity *r)
2050 {
2051 SEC_DESC *psd = NULL;
2052 size_t sd_size;
2053 fstring servicename;
2054 SMB_STRUCT_STAT st;
2055 NTSTATUS nt_status;
2056 WERROR werr;
2057 connection_struct *conn = NULL;
2058 struct sec_desc_buf *sd_buf = NULL;
2059 files_struct *fsp = NULL;
2060 int snum;
2061 char *oldcwd = NULL;
2062
2063 ZERO_STRUCT(st);
2064
2065 fstrcpy(servicename, r->in.share);
2066
2067 snum = find_service(servicename);
2068 if (snum == -1) {
2069 DEBUG(10, ("Could not find service %s\n", servicename));
2070 werr = WERR_NET_NAME_NOT_FOUND;
2071 goto error_exit;
2072 }
2073
2074 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2075 lp_pathname(snum), p->server_info,
2076 &oldcwd);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2078 DEBUG(10, ("create_conn_struct failed: %s\n",
2079 nt_errstr(nt_status)));
2080 werr = ntstatus_to_werror(nt_status);
2081 goto error_exit;
2082 }
2083
2084 nt_status = SMB_VFS_CREATE_FILE(
2085 conn, /* conn */
2086 NULL, /* req */
2087 0, /* root_dir_fid */
2088 r->in.file, /* fname */
2089 CFF_DOS_PATH, /* create_file_flags */
2090 FILE_READ_ATTRIBUTES, /* access_mask */
2091 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2092 FILE_OPEN, /* create_disposition*/
2093 0, /* create_options */
2094 0, /* file_attributes */
2095 INTERNAL_OPEN_ONLY, /* oplock_request */
2096 0, /* allocation_size */
2097 NULL, /* sd */
2098 NULL, /* ea_list */
2099 &fsp, /* result */
2100 NULL, /* pinfo */
2101 NULL); /* psbuf */
2102
2103 if (!NT_STATUS_IS_OK(nt_status)) {
2104 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2105 r->in.file));
2106 werr = ntstatus_to_werror(nt_status);
2107 goto error_exit;
2108 }
2109
2110 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2111 (OWNER_SECURITY_INFORMATION
2112 |GROUP_SECURITY_INFORMATION
2113 |DACL_SECURITY_INFORMATION), &psd);
2114
2115 if (!NT_STATUS_IS_OK(nt_status)) {
2116 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2117 "for file %s\n", r->in.file));
2118 werr = ntstatus_to_werror(nt_status);
2119 goto error_exit;
2120 }
2121
2122 sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2123
2124 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2125 if (!sd_buf) {
2126 werr = WERR_NOMEM;
2127 goto error_exit;
2128 }
2129
2130 sd_buf->sd_size = sd_size;
2131 sd_buf->sd = psd;
2132
2133 *r->out.sd_buf = sd_buf;
2134
2135 psd->dacl->revision = NT4_ACL_REVISION;
2136
2137 close_file(NULL, fsp, NORMAL_CLOSE);
2138 vfs_ChDir(conn, oldcwd);
2139 conn_free_internal(conn);
2140 return WERR_OK;
2141
2142 error_exit:
2143
2144 if (fsp) {
2145 close_file(NULL, fsp, NORMAL_CLOSE);
2146 }
2147
2148 if (oldcwd) {
2149 vfs_ChDir(conn, oldcwd);
2150 }
2151
2152 if (conn) {
2153 conn_free_internal(conn);
2154 }
2155
2156 return werr;
2157 }
2158
2159 /***********************************************************************************
2160 _srvsvc_NetSetFileSecurity
2161 Win9x NT tools set security descriptor.
2162 ***********************************************************************************/
2163
2164 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
2165 struct srvsvc_NetSetFileSecurity *r)
2166 {
2167 fstring servicename;
2168 files_struct *fsp = NULL;
2169 SMB_STRUCT_STAT st;
2170 NTSTATUS nt_status;
2171 WERROR werr;
2172 connection_struct *conn = NULL;
2173 int snum;
2174 char *oldcwd = NULL;
2175 struct security_descriptor *psd = NULL;
2176 uint32_t security_info_sent = 0;
2177
2178 ZERO_STRUCT(st);
2179
2180 fstrcpy(servicename, r->in.share);
2181
2182 snum = find_service(servicename);
2183 if (snum == -1) {
2184 DEBUG(10, ("Could not find service %s\n", servicename));
2185 werr = WERR_NET_NAME_NOT_FOUND;
2186 goto error_exit;
2187 }
2188
2189 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2190 lp_pathname(snum), p->server_info,
2191 &oldcwd);
2192 if (!NT_STATUS_IS_OK(nt_status)) {
2193 DEBUG(10, ("create_conn_struct failed: %s\n",
2194 nt_errstr(nt_status)));
2195 werr = ntstatus_to_werror(nt_status);
2196 goto error_exit;
2197 }
2198
2199 nt_status = SMB_VFS_CREATE_FILE(
2200 conn, /* conn */
2201 NULL, /* req */
2202 0, /* root_dir_fid */
2203 r->in.file, /* fname */
2204 CFF_DOS_PATH, /* create_file_flags */
2205 FILE_WRITE_ATTRIBUTES, /* access_mask */
2206 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2207 FILE_OPEN, /* create_disposition*/
2208 0, /* create_options */
2209 0, /* file_attributes */
2210 INTERNAL_OPEN_ONLY, /* oplock_request */
2211 0, /* allocation_size */
2212 NULL, /* sd */
2213 NULL, /* ea_list */
2214 &fsp, /* result */
2215 NULL, /* pinfo */
2216 NULL); /* psbuf */
2217
2218 if (!NT_STATUS_IS_OK(nt_status)) {
2219 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2220 r->in.file));
2221 werr = ntstatus_to_werror(nt_status);
2222 goto error_exit;
2223 }
2224
2225 psd = r->in.sd_buf->sd;
2226 security_info_sent = r->in.securityinformation;
2227
2228 if (psd->owner_sid==0) {
2229 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2230 }
2231 if (psd->group_sid==0) {
2232 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2233 }
2234 if (psd->sacl==0) {
2235 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2236 }
2237 if (psd->dacl==0) {
2238 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2239 }
2240
2241 /* Convert all the generic bits. */
2242 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2243 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2244
2245 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2246 security_info_sent,
2247 psd);
2248
2249 if (!NT_STATUS_IS_OK(nt_status) ) {
2250 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2251 "on file %s\n", r->in.share));
2252 werr = WERR_ACCESS_DENIED;
2253 goto error_exit;
2254 }
2255
2256 close_file(NULL, fsp, NORMAL_CLOSE);
2257 vfs_ChDir(conn, oldcwd);
2258 conn_free_internal(conn);
2259 return WERR_OK;
2260
2261 error_exit:
2262
2263 if (fsp) {
2264 close_file(NULL, fsp, NORMAL_CLOSE);
2265 }
2266
2267 if (oldcwd) {
2268 vfs_ChDir(conn, oldcwd);
2269 }
2270
2271 if (conn) {
2272 conn_free_internal(conn);
2273 }
2274
2275 return werr;
2276 }
2277
2278 /***********************************************************************************
2279 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2280 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2281 These disks would the disks listed by this function.
2282 Users could then create shares relative to these disks. Watch out for moving these disks around.
2283 "Nigel Williams" <nigel@veritas.com>.
2284 ***********************************************************************************/
2285
2286 static const char *server_disks[] = {"C:"};
2287
2288 static uint32 get_server_disk_count(void)
/* [<][>][^][v][top][bottom][index][help] */
2289 {
2290 return sizeof(server_disks)/sizeof(server_disks[0]);
2291 }
2292
2293 static uint32 init_server_disk_enum(uint32 *resume)
/* [<][>][^][v][top][bottom][index][help] */
2294 {
2295 uint32 server_disk_count = get_server_disk_count();
2296
2297 /*resume can be an offset into the list for now*/
2298
2299 if(*resume & 0x80000000)
2300 *resume = 0;
2301
2302 if(*resume > server_disk_count)
2303 *resume = server_disk_count;
2304
2305 return server_disk_count - *resume;
2306 }
2307
2308 static const char *next_server_disk_enum(uint32 *resume)
/* [<][>][^][v][top][bottom][index][help] */
2309 {
2310 const char *disk;
2311
2312 if(init_server_disk_enum(resume) == 0)
2313 return NULL;
2314
2315 disk = server_disks[*resume];
2316
2317 (*resume)++;
2318
2319 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2320
2321 return disk;
2322 }
2323
2324 /********************************************************************
2325 _srvsvc_NetDiskEnum
2326 ********************************************************************/
2327
2328 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
2329 struct srvsvc_NetDiskEnum *r)
2330 {
2331 uint32 i;
2332 const char *disk_name;
2333 TALLOC_CTX *ctx = p->mem_ctx;
2334 WERROR werr;
2335 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2336
2337 werr = WERR_OK;
2338
2339 *r->out.totalentries = init_server_disk_enum(&resume);
2340
2341 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2342 MAX_SERVER_DISK_ENTRIES);
2343 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2344
2345 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2346
2347 r->out.info->count = 0;
2348
2349 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2350
2351 r->out.info->count++;
2352
2353 /*copy disk name into a unicode string*/
2354
2355 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2356 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2357 }
2358
2359 /* add a terminating null string. Is this there if there is more data to come? */
2360
2361 r->out.info->count++;
2362
2363 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2364 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2365
2366 if (r->out.resume_handle) {
2367 *r->out.resume_handle = resume;
2368 }
2369
2370 return werr;
2371 }
2372
2373 /********************************************************************
2374 _srvsvc_NetNameValidate
2375 ********************************************************************/
2376
2377 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
/* [<][>][^][v][top][bottom][index][help] */
2378 struct srvsvc_NetNameValidate *r)
2379 {
2380 switch (r->in.name_type) {
2381 case 0x9:
2382 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2383 strlen_m(r->in.name)))
2384 {
2385 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2386 r->in.name));
2387 return WERR_INVALID_NAME;
2388 }
2389 break;
2390
2391 default:
2392 return WERR_UNKNOWN_LEVEL;
2393 }
2394
2395 return WERR_OK;
2396 }
2397
2398 /*******************************************************************
2399 ********************************************************************/
2400
2401 static void enum_file_close_fn( const struct share_mode_entry *e,
/* [<][>][^][v][top][bottom][index][help] */
2402 const char *sharepath, const char *fname,
2403 void *private_data )
2404 {
2405 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2406 struct srvsvc_NetFileClose *r =
2407 (struct srvsvc_NetFileClose *)private_data;
2408 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2409
2410 if (fid != r->in.fid) {
2411 return; /* Not this file. */
2412 }
2413
2414 if (!process_exists(e->pid) ) {
2415 return;
2416 }
2417
2418 /* Ok - send the close message. */
2419 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2420 sharepath,
2421 share_mode_str(talloc_tos(), 0, e) ));
2422
2423 share_mode_entry_to_message(msg, e);
2424
2425 r->out.result = ntstatus_to_werror(
2426 messaging_send_buf(smbd_messaging_context(),
2427 e->pid, MSG_SMB_CLOSE_FILE,
2428 (uint8 *)msg,
2429 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2430 }
2431
2432 /********************************************************************
2433 Close a file given a 32-bit file id.
2434 ********************************************************************/
2435
2436 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
/* [<][>][^][v][top][bottom][index][help] */
2437 {
2438 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2439 bool is_disk_op;
2440
2441 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2442
2443 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2444
2445 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2446 return WERR_ACCESS_DENIED;
2447 }
2448
2449 /* enum_file_close_fn sends the close message to
2450 * the relevent smbd process. */
2451
2452 r->out.result = WERR_BADFILE;
2453 share_mode_forall( enum_file_close_fn, (void *)r);
2454 return r->out.result;
2455 }
2456
2457 /********************************************************************
2458 ********************************************************************/
2459
2460 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
/* [<][>][^][v][top][bottom][index][help] */
2461 {
2462 p->rng_fault_state = True;
2463 return WERR_NOT_SUPPORTED;
2464 }
2465
2466 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
/* [<][>][^][v][top][bottom][index][help] */
2467 {
2468 p->rng_fault_state = True;
2469 return WERR_NOT_SUPPORTED;
2470 }
2471
2472 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
/* [<][>][^][v][top][bottom][index][help] */
2473 {
2474 p->rng_fault_state = True;
2475 return WERR_NOT_SUPPORTED;
2476 }
2477
2478 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
/* [<][>][^][v][top][bottom][index][help] */
2479 {
2480 p->rng_fault_state = True;
2481 return WERR_NOT_SUPPORTED;
2482 }
2483
2484 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
/* [<][>][^][v][top][bottom][index][help] */
2485 {
2486 p->rng_fault_state = True;
2487 return WERR_NOT_SUPPORTED;
2488 }
2489
2490 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
/* [<][>][^][v][top][bottom][index][help] */
2491 {
2492 p->rng_fault_state = True;
2493 return WERR_NOT_SUPPORTED;
2494 }
2495
2496 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
/* [<][>][^][v][top][bottom][index][help] */
2497 {
2498 p->rng_fault_state = True;
2499 return WERR_NOT_SUPPORTED;
2500 }
2501
2502 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
/* [<][>][^][v][top][bottom][index][help] */
2503 {
2504 p->rng_fault_state = True;
2505 return WERR_NOT_SUPPORTED;
2506 }
2507
2508 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
/* [<][>][^][v][top][bottom][index][help] */
2509 {
2510 p->rng_fault_state = True;
2511 return WERR_NOT_SUPPORTED;
2512 }
2513
2514 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
/* [<][>][^][v][top][bottom][index][help] */
2515 {
2516 p->rng_fault_state = True;
2517 return WERR_NOT_SUPPORTED;
2518 }
2519
2520 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
/* [<][>][^][v][top][bottom][index][help] */
2521 {
2522 p->rng_fault_state = True;
2523 return WERR_NOT_SUPPORTED;
2524 }
2525
2526 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
/* [<][>][^][v][top][bottom][index][help] */
2527 {
2528 p->rng_fault_state = True;
2529 return WERR_NOT_SUPPORTED;
2530 }
2531
2532 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
/* [<][>][^][v][top][bottom][index][help] */
2533 {
2534 p->rng_fault_state = True;
2535 return WERR_NOT_SUPPORTED;
2536 }
2537
2538 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
/* [<][>][^][v][top][bottom][index][help] */
2539 {
2540 p->rng_fault_state = True;
2541 return WERR_NOT_SUPPORTED;
2542 }
2543
2544 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
/* [<][>][^][v][top][bottom][index][help] */
2545 {
2546 p->rng_fault_state = True;
2547 return WERR_NOT_SUPPORTED;
2548 }
2549
2550 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
/* [<][>][^][v][top][bottom][index][help] */
2551 {
2552 p->rng_fault_state = True;
2553 return WERR_NOT_SUPPORTED;
2554 }
2555
2556 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
/* [<][>][^][v][top][bottom][index][help] */
2557 {
2558 p->rng_fault_state = True;
2559 return WERR_NOT_SUPPORTED;
2560 }
2561
2562 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
/* [<][>][^][v][top][bottom][index][help] */
2563 {
2564 p->rng_fault_state = True;
2565 return WERR_NOT_SUPPORTED;
2566 }
2567
2568 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
/* [<][>][^][v][top][bottom][index][help] */
2569 {
2570 p->rng_fault_state = True;
2571 return WERR_NOT_SUPPORTED;
2572 }
2573
2574 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
/* [<][>][^][v][top][bottom][index][help] */
2575 {
2576 p->rng_fault_state = True;
2577 return WERR_NOT_SUPPORTED;
2578 }
2579
2580 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
/* [<][>][^][v][top][bottom][index][help] */
2581 {
2582 p->rng_fault_state = True;
2583 return WERR_NOT_SUPPORTED;
2584 }
2585
2586 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
/* [<][>][^][v][top][bottom][index][help] */
2587 {
2588 p->rng_fault_state = True;
2589 return WERR_NOT_SUPPORTED;
2590 }
2591
2592 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
/* [<][>][^][v][top][bottom][index][help] */
2593 {
2594 p->rng_fault_state = True;
2595 return WERR_NOT_SUPPORTED;
2596 }
2597
2598 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
/* [<][>][^][v][top][bottom][index][help] */
2599 {
2600 p->rng_fault_state = True;
2601 return WERR_NOT_SUPPORTED;
2602 }
2603
2604 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
/* [<][>][^][v][top][bottom][index][help] */
2605 {
2606 p->rng_fault_state = True;
2607 return WERR_NOT_SUPPORTED;
2608 }
2609
2610 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
/* [<][>][^][v][top][bottom][index][help] */
2611 {
2612 p->rng_fault_state = True;
2613 return WERR_NOT_SUPPORTED;
2614 }
2615
2616 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
/* [<][>][^][v][top][bottom][index][help] */
2617 {
2618 p->rng_fault_state = True;
2619 return WERR_NOT_SUPPORTED;
2620 }
2621
2622 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
/* [<][>][^][v][top][bottom][index][help] */
2623 {
2624 p->rng_fault_state = True;
2625 return WERR_NOT_SUPPORTED;
2626 }
2627
2628 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
/* [<][>][^][v][top][bottom][index][help] */
2629 {
2630 p->rng_fault_state = True;
2631 return WERR_NOT_SUPPORTED;
2632 }
2633
2634 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
/* [<][>][^][v][top][bottom][index][help] */
2635 {
2636 p->rng_fault_state = True;
2637 return WERR_NOT_SUPPORTED;
2638 }
2639
2640 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
/* [<][>][^][v][top][bottom][index][help] */
2641 {
2642 p->rng_fault_state = True;
2643 return WERR_NOT_SUPPORTED;
2644 }
2645
2646 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
/* [<][>][^][v][top][bottom][index][help] */
2647 {
2648 p->rng_fault_state = True;
2649 return WERR_NOT_SUPPORTED;
2650 }
2651
2652 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
/* [<][>][^][v][top][bottom][index][help] */
2653 {
2654 p->rng_fault_state = True;
2655 return WERR_NOT_SUPPORTED;
2656 }
2657
2658 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
/* [<][>][^][v][top][bottom][index][help] */
2659 {
2660 p->rng_fault_state = True;
2661 return WERR_NOT_SUPPORTED;
2662 }
2663
2664 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
/* [<][>][^][v][top][bottom][index][help] */
2665 {
2666 p->rng_fault_state = True;
2667 return WERR_NOT_SUPPORTED;
2668 }
2669