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