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