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