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