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