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