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) Jelmer Vernooij 2006.
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 2 of the License, or
13 * (at your option) any later version.
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.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
29 #define MAX_SERVER_DISK_ENTRIES 15
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
35 #define DBGC_CLASS DBGC_RPC_SRV
37 /* Use for enumerating connections, pipes, & files */
39 struct file_enum_count {
42 struct srvsvc_NetFileInfo3 *info;
45 struct sess_file_count {
51 /****************************************************************************
52 Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
57 struct pipe_open_rec prec;
58 struct file_enum_count *fenum = (struct file_enum_count *)p;
60 if (dbuf.dsize != sizeof(struct pipe_open_rec))
63 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
65 if ( process_exists(prec.pid) ) {
66 struct srvsvc_NetFileInfo3 *f;
70 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
72 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
74 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
80 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82 fenum->info[i].num_locks = 0;
83 if (!(fenum->info[i].user = talloc_strdup(
84 fenum->ctx, uidtoname(prec.uid)))) {
85 /* There's not much we can do here. */
86 fenum->info[i].user = "";
88 if (!(fenum->info[i].path = talloc_strdup(
89 fenum->ctx, fullpath))) {
90 /* There's not much we can do here. */
91 fenum->info[i].path = "";
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
104 uint32 *count, uint32 *resume )
106 struct file_enum_count fenum;
110 fenum.count = *count;
112 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
113 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
119 *count = fenum.count;
124 /*******************************************************************
125 ********************************************************************/
127 /* global needed to make use of the share_mode_forall() callback */
128 static struct file_enum_count f_enum_cnt;
130 static void enum_file_fn( const struct share_mode_entry *e,
131 const char *sharepath, const char *fname,
134 struct file_enum_count *fenum = &f_enum_cnt;
136 /* If the pid was not found delete the entry from connections.tdb */
138 if ( process_exists(e->pid) ) {
139 struct srvsvc_NetFileInfo3 *f;
140 int i = fenum->count;
142 struct byte_range_lock *brl;
147 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
149 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
154 /* need to count the number of locks on a file */
158 fsp.inode = e->inode;
160 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
161 num_locks = brl->num_locks;
165 if ( strcmp( fname, "." ) == 0 ) {
166 pstr_sprintf( fullpath, "C:%s", sharepath );
168 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
170 string_replace( fullpath, '/', '\\' );
172 /* mask out create (what ever that is) */
173 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
175 fenum->info[i].fid = e->share_file_id;
176 fenum->info[i].permissions = permissions;
177 fenum->info[i].num_locks = num_locks;
178 if (!(fenum->info[i].user = talloc_strdup(
179 fenum->ctx, uidtoname(e->uid)))) {
180 /* There's not much we can do here. */
181 fenum->info[i].user = "";
183 if (!(fenum->info[i].path = talloc_strdup(
184 fenum->ctx, fullpath))) {
185 /* There's not much we can do here. */
186 fenum->info[i].path = "";
196 /*******************************************************************
197 ********************************************************************/
199 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
200 uint32 *count, uint32 *resume )
202 f_enum_cnt.ctx = ctx;
203 f_enum_cnt.count = *count;
204 f_enum_cnt.info = *info;
206 share_mode_forall( enum_file_fn, NULL );
208 *info = f_enum_cnt.info;
209 *count = f_enum_cnt.count;
214 /*******************************************************************
215 Utility function to get the 'type' of a share from a share definition.
216 ********************************************************************/
217 static uint32 get_share_type(const struct share_params *params)
219 char *net_name = lp_servicename(params->service);
220 int len_net_name = strlen(net_name);
222 /* work out the share type */
223 uint32 type = STYPE_DISKTREE;
225 if (lp_print_ok(params->service))
227 if (strequal(lp_fstype(params->service), "IPC"))
229 if (net_name[len_net_name-1] == '$')
230 type |= STYPE_HIDDEN;
235 /*******************************************************************
236 Fill in a share info level 0 structure.
237 ********************************************************************/
239 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
240 const struct share_params *params)
242 sh0->name = lp_servicename(params->service);
245 /*******************************************************************
246 Fill in a share info level 1 structure.
247 ********************************************************************/
249 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
250 const struct share_params *params)
252 connection_struct *conn = p->conn;
254 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
255 conn->user, conn->connectpath, conn->gid,
256 get_current_username(),
257 current_user_info.domain,
258 lp_comment(params->service));
260 sh1->name = lp_servicename(params->service);
261 sh1->type = get_share_type(params);
264 /*******************************************************************
265 Fill in a share info level 2 structure.
266 ********************************************************************/
268 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
269 const struct share_params *params)
271 connection_struct *conn = p->conn;
274 int max_connections = lp_max_connections(params->service);
275 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
277 char *net_name = lp_servicename(params->service);
279 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
280 conn->user, conn->connectpath, conn->gid,
281 get_current_username(),
282 current_user_info.domain,
283 lp_comment(params->service));
284 path = talloc_asprintf(p->mem_ctx, "C:%s",
285 lp_pathname(params->service));
288 * Change / to \\ so that win2k will see it as a valid path. This was
289 * added to enable use of browsing in win2k add share dialog.
292 string_replace(path, '/', '\\');
294 count = count_current_connections( net_name, False );
295 sh2->name = net_name;
296 sh2->type = get_share_type(params);
297 sh2->comment = remark;
298 sh2->permissions = 0;
299 sh2->max_users = max_uses;
300 sh2->current_users = count;
305 /*******************************************************************
306 Map any generic bits to file specific bits.
307 ********************************************************************/
309 static void map_generic_share_sd_bits(SEC_DESC *psd)
312 SEC_ACL *ps_dacl = NULL;
321 for (i = 0; i < ps_dacl->num_aces; i++) {
322 SEC_ACE *psa = &ps_dacl->aces[i];
323 uint32 orig_mask = psa->access_mask;
325 se_map_generic(&psa->access_mask, &file_generic_mapping);
326 psa->access_mask |= orig_mask;
330 /*******************************************************************
331 Fill in a share info level 501 structure.
332 ********************************************************************/
334 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
335 const struct share_params *params)
337 connection_struct *conn = p->conn;
339 const char *net_name = lp_servicename(params->service);
341 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
342 conn->user, conn->connectpath, conn->gid,
343 get_current_username(),
344 current_user_info.domain,
345 lp_comment(params->service));
348 sh501->name = net_name;
349 sh501->type = get_share_type(params);
350 sh501->comment = remark;
351 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
354 /*******************************************************************
355 Fill in a share info level 502 structure.
356 ********************************************************************/
358 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
359 const struct share_params *params)
361 int max_connections = lp_max_connections(params->service);
362 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
363 connection_struct *conn = p->conn;
370 TALLOC_CTX *ctx = p->mem_ctx;
375 net_name = lp_servicename(params->service);
376 count = count_current_connections( net_name, False );
378 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
379 conn->user, conn->connectpath, conn->gid,
380 get_current_username(),
381 current_user_info.domain,
382 lp_comment(params->service));
384 path = talloc_asprintf(p->mem_ctx, "C:%s",
385 lp_pathname(params->service));
388 * Change / to \\ so that win2k will see it as a valid path. This was
389 * added to enable use of browsing in win2k add share dialog.
392 string_replace(path, '/', '\\');
394 sd = get_share_security(ctx, lp_servicename(params->service),
397 sh502->name = net_name;
398 sh502->type = get_share_type(params);
399 sh502->comment = remark;
401 sh502->password = "";
403 sh502->permissions = 0;
404 sh502->max_users = max_uses;
405 sh502->current_users = count;
409 /***************************************************************************
410 Fill in a share info level 1004 structure.
411 ***************************************************************************/
413 static void init_srv_share_info_1004(pipes_struct *p,
414 struct srvsvc_NetShareInfo1004* sh1004,
415 const struct share_params *params)
417 connection_struct *conn = p->conn;
420 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
421 conn->user, conn->connectpath, conn->gid,
422 get_current_username(),
423 current_user_info.domain,
424 lp_comment(params->service));
426 ZERO_STRUCTP(sh1004);
428 sh1004->comment = remark;
431 /***************************************************************************
432 Fill in a share info level 1005 structure.
433 ***************************************************************************/
435 static void init_srv_share_info_1005(pipes_struct *p,
436 struct srvsvc_NetShareInfo1005* sh1005,
437 const struct share_params *params)
439 sh1005->dfs_flags = 0;
441 if(lp_host_msdfs() && lp_msdfs_root(params->service))
443 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
445 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
447 /***************************************************************************
448 Fill in a share info level 1006 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1006(pipes_struct *p,
452 struct srvsvc_NetShareInfo1006* sh1006,
453 const struct share_params *params)
455 sh1006->max_users = -1;
458 /***************************************************************************
459 Fill in a share info level 1007 structure.
460 ***************************************************************************/
462 static void init_srv_share_info_1007(pipes_struct *p,
463 struct srvsvc_NetShareInfo1007* sh1007,
464 const struct share_params *params)
468 ZERO_STRUCTP(sh1007);
470 sh1007->flags = flags;
471 sh1007->alternate_directory_name = "";
474 /*******************************************************************
475 Fill in a share info level 1501 structure.
476 ********************************************************************/
478 static void init_srv_share_info_1501(pipes_struct *p,
479 struct sec_desc_buf *sh1501,
480 const struct share_params *params)
484 TALLOC_CTX *ctx = p->mem_ctx;
486 ZERO_STRUCTP(sh1501);
488 sd = get_share_security(ctx, lp_servicename(params->service),
494 /*******************************************************************
495 True if it ends in '$'.
496 ********************************************************************/
498 static BOOL is_hidden_share(const struct share_params *params)
500 const char *net_name = lp_servicename(params->service);
502 return (net_name[strlen(net_name) - 1] == '$');
505 /*******************************************************************
506 Fill in a share info structure.
507 ********************************************************************/
509 static WERROR init_srv_share_info_ctr(pipes_struct *p,
510 union srvsvc_NetShareCtr *ctr,
511 uint32 info_level, uint32 *resume_hnd,
512 uint32 *total_entries, BOOL all_shares)
514 TALLOC_CTX *ctx = p->mem_ctx;
515 struct share_iterator *shares;
516 struct share_params *share;
517 WERROR result = WERR_NOMEM;
519 DEBUG(5,("init_srv_share_info_ctr\n"));
527 /* Ensure all the usershares are loaded. */
529 load_usershare_shares();
530 load_registry_shares();
535 if (!(shares = share_list_all(ctx))) {
536 DEBUG(5, ("Could not list shares\n"));
537 return WERR_ACCESS_DENIED;
540 switch (info_level) {
542 if (!(ctr->ctr0 = TALLOC_ZERO_P(
543 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
548 if (!(ctr->ctr1 = TALLOC_ZERO_P(
549 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
554 if (!(ctr->ctr2 = TALLOC_ZERO_P(
555 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
560 if (!(ctr->ctr501 = TALLOC_ZERO_P(
561 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
566 if (!(ctr->ctr502 = TALLOC_ZERO_P(
567 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
572 if (!(ctr->ctr1004 = TALLOC_ZERO_P(
573 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
578 if (!(ctr->ctr1005 = TALLOC_ZERO_P(
579 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
584 if (!(ctr->ctr1006 = TALLOC_ZERO_P(
585 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
590 if (!(ctr->ctr1007 = TALLOC_ZERO_P(
591 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
596 if (!(ctr->ctr1501 = TALLOC_ZERO_P(
597 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
602 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
603 "value %d\n", info_level));
604 return WERR_UNKNOWN_LEVEL;
607 while ((share = next_share(shares)) != NULL) {
608 if (!lp_browseable(share->service)) {
611 if (!all_shares && is_hidden_share(share)) {
615 switch (info_level) {
618 struct srvsvc_NetShareInfo0 i;
619 init_srv_share_info_0(p, &i, share);
620 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
621 &ctr->ctr0->array, &ctr->ctr0->count);
622 if (ctr->ctr0->array == NULL) {
625 *total_entries = ctr->ctr0->count;
631 struct srvsvc_NetShareInfo1 i;
632 init_srv_share_info_1(p, &i, share);
633 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
634 &ctr->ctr1->array, &ctr->ctr1->count);
635 if (ctr->ctr1->array == NULL) {
638 *total_entries = ctr->ctr1->count;
644 struct srvsvc_NetShareInfo2 i;
645 init_srv_share_info_2(p, &i, share);
646 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
647 &ctr->ctr2->array, &ctr->ctr2->count);
648 if (ctr->ctr2->array == NULL) {
651 *total_entries = ctr->ctr2->count;
657 struct srvsvc_NetShareInfo501 i;
658 init_srv_share_info_501(p, &i, share);
659 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
660 &ctr->ctr501->array, &ctr->ctr501->count);
661 if (ctr->ctr501->array == NULL) {
664 *total_entries = ctr->ctr501->count;
670 struct srvsvc_NetShareInfo502 i;
671 init_srv_share_info_502(p, &i, share);
672 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
673 &ctr->ctr502->array, &ctr->ctr502->count);
674 if (ctr->ctr502->array == NULL) {
677 *total_entries = ctr->ctr502->count;
681 /* here for completeness but not currently used with enum
686 struct srvsvc_NetShareInfo1004 i;
687 init_srv_share_info_1004(p, &i, share);
688 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
689 &ctr->ctr1004->array, &ctr->ctr1004->count);
690 if (ctr->ctr1004->array == NULL) {
693 *total_entries = ctr->ctr1004->count;
699 struct srvsvc_NetShareInfo1005 i;
700 init_srv_share_info_1005(p, &i, share);
701 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
702 &ctr->ctr1005->array, &ctr->ctr1005->count);
703 if (ctr->ctr1005->array == NULL) {
706 *total_entries = ctr->ctr1005->count;
712 struct srvsvc_NetShareInfo1006 i;
713 init_srv_share_info_1006(p, &i, share);
714 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
715 &ctr->ctr1006->array, &ctr->ctr1006->count);
716 if (ctr->ctr1006->array == NULL) {
719 *total_entries = ctr->ctr1006->count;
725 struct srvsvc_NetShareInfo1007 i;
726 init_srv_share_info_1007(p, &i, share);
727 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
728 &ctr->ctr1007->array, &ctr->ctr1007->count);
729 if (ctr->ctr1007->array == NULL) {
732 *total_entries = ctr->ctr1007->count;
738 struct sec_desc_buf i;
739 init_srv_share_info_1501(p, &i, share);
740 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
741 &ctr->ctr1501->array, &ctr->ctr1501->count);
742 if (ctr->ctr1501->array == NULL) {
745 *total_entries = ctr->ctr1501->count;
759 /*******************************************************************
760 fill in a sess info level 0 structure.
761 ********************************************************************/
763 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
765 struct sessionid *session_list;
766 uint32 num_entries = 0;
767 (*stot) = list_sessions(p->mem_ctx, &session_list);
776 DEBUG(5,("init_srv_sess_0_ss0\n"));
778 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
781 for (; (*snum) < (*stot); (*snum)++) {
782 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
786 ss0->count = num_entries;
788 if ((*snum) >= (*stot)) {
798 /*******************************************************************
799 ********************************************************************/
801 static void sess_file_fn( const struct share_mode_entry *e,
802 const char *sharepath, const char *fname,
805 struct sess_file_count *sess = (struct sess_file_count *)private_data;
807 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
814 /*******************************************************************
815 ********************************************************************/
817 static int net_count_files( uid_t uid, struct server_id pid )
819 struct sess_file_count s_file_cnt;
821 s_file_cnt.count = 0;
822 s_file_cnt.uid = uid;
823 s_file_cnt.pid = pid;
825 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
827 return s_file_cnt.count;
830 /*******************************************************************
831 fill in a sess info level 1 structure.
832 ********************************************************************/
834 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
836 struct sessionid *session_list;
837 uint32 num_entries = 0;
838 time_t now = time(NULL);
855 (*stot) = list_sessions(p->mem_ctx, &session_list);
857 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
859 for (; (*snum) < (*stot); (*snum)++) {
862 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
866 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
867 session_list[*snum].username));
871 connect_time = (uint32)(now - session_list[*snum].connect_start);
872 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
873 guest = strequal( session_list[*snum].username, lp_guestaccount() );
875 if (!(ss1->array[num_entries].client = talloc_strdup(
876 ss1->array, session_list[*snum].remote_machine))) {
877 ss1->array[num_entries].client = "";
879 if (!(ss1->array[num_entries].user = talloc_strdup(
880 ss1->array, session_list[*snum].username))) {
881 ss1->array[num_entries].user = "";
883 ss1->array[num_entries].num_open = num_files;
884 ss1->array[num_entries].time = connect_time;
885 ss1->array[num_entries].idle_time = 0;
886 ss1->array[num_entries].user_flags = guest;
891 ss1->count = num_entries;
893 if ((*snum) >= (*stot)) {
898 /*******************************************************************
899 makes a SRV_R_NET_SESS_ENUM structure.
900 ********************************************************************/
902 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
903 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
905 WERROR status = WERR_OK;
906 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
908 switch (switch_value) {
910 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
911 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
914 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
915 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
918 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
919 if (resume_hnd != NULL)
921 (*total_entries) = 0;
923 status = WERR_UNKNOWN_LEVEL;
930 /*******************************************************************
931 fill in a conn info level 0 structure.
932 ********************************************************************/
934 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
936 uint32 num_entries = 0;
945 DEBUG(5,("init_srv_conn_0_ss0\n"));
948 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
949 for (; (*snum) < (*stot); (*snum)++) {
951 ss0->array[num_entries].conn_id = (*stot);
953 /* move on to creating next connection */
954 /* move on to creating next conn */
958 ss0->count = num_entries;
960 if ((*snum) >= (*stot)) {
972 /*******************************************************************
973 fill in a conn info level 1 structure.
974 ********************************************************************/
976 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
978 uint32 num_entries = 0;
987 DEBUG(5,("init_srv_conn_1_ss1\n"));
990 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
991 for (; (*snum) < (*stot); (*snum)++) {
992 ss1->array[num_entries].conn_id = (*stot);
993 ss1->array[num_entries].conn_type = 0x3;
994 ss1->array[num_entries].num_open = 1;
995 ss1->array[num_entries].num_users = 1;
996 ss1->array[num_entries].conn_time = 3;
997 ss1->array[num_entries].user = "dummy_user";
998 ss1->array[num_entries].share = "IPC$";
1000 /* move on to creating next connection */
1001 /* move on to creating next conn */
1005 ss1->count = num_entries;
1007 if ((*snum) >= (*stot)) {
1019 /*******************************************************************
1020 makes a SRV_R_NET_CONN_ENUM structure.
1021 ********************************************************************/
1023 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1024 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1026 WERROR status = WERR_OK;
1027 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1029 switch (switch_value) {
1031 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1034 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1037 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1040 (*total_entries) = 0;
1041 status = WERR_UNKNOWN_LEVEL;
1048 /*******************************************************************
1049 makes a SRV_R_NET_FILE_ENUM structure.
1050 ********************************************************************/
1052 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1054 TALLOC_CTX *ctx = get_talloc_ctx();
1057 /* TODO -- Windows enumerates
1059 (c) open directories and files */
1061 ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3);
1063 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1064 if ( !W_ERROR_IS_OK(status))
1067 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1068 if ( !W_ERROR_IS_OK(status))
1071 ctr->ctr3->count = *num_entries;
1076 /*******************************************************************
1077 *******************************************************************/
1079 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1081 switch ( *r->in.level ) {
1083 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.totalentries );
1085 return WERR_UNKNOWN_LEVEL;
1091 /*******************************************************************
1093 ********************************************************************/
1095 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1097 WERROR status = WERR_OK;
1099 ZERO_STRUCTP(r->out.info);
1101 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1103 if (!pipe_access_check(p)) {
1104 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1105 return WERR_ACCESS_DENIED;
1108 switch (r->in.level) {
1110 /* Technically level 102 should only be available to
1111 Administrators but there isn't anything super-secret
1112 here, as most of it is made up. */
1115 r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1117 r->out.info->info102->platform_id = 500;
1118 r->out.info->info102->version_major = lp_major_announce_version();
1119 r->out.info->info102->version_minor = lp_minor_announce_version();
1120 r->out.info->info102->server_name = global_myname();
1121 r->out.info->info102->server_type = lp_default_server_announce();
1122 r->out.info->info102->userpath = "C:\\";
1123 r->out.info->info102->licenses = 10000;
1124 r->out.info->info102->anndelta = 3000;
1125 r->out.info->info102->disc = 0xf;
1126 r->out.info->info102->users = 0xffffffff;
1127 r->out.info->info102->hidden = 0;
1128 r->out.info->info102->announce = 240;
1129 r->out.info->info102->comment = lp_serverstring();
1132 r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1133 r->out.info->info101->platform_id = 500;
1134 r->out.info->info101->server_name = global_myname();
1135 r->out.info->info101->version_major = lp_major_announce_version();
1136 r->out.info->info101->version_minor = lp_minor_announce_version();
1137 r->out.info->info101->server_type = lp_default_server_announce();
1138 r->out.info->info101->comment = lp_serverstring();
1141 r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1142 r->out.info->info100->platform_id = 500;
1143 r->out.info->info100->server_name = global_myname();
1146 return WERR_UNKNOWN_LEVEL;
1150 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1155 /*******************************************************************
1157 ********************************************************************/
1159 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1161 /* Set up the net server set info structure. */
1162 if (r->out.parm_error) {
1163 *r->out.parm_error = 0;
1168 /*******************************************************************
1170 ********************************************************************/
1172 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1174 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1176 ZERO_STRUCTP(r->out.ctr);
1179 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1182 /*******************************************************************
1184 ********************************************************************/
1186 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1188 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1190 ZERO_STRUCTP(r->out.ctr);
1193 return init_srv_sess_info_ctr(p, r->out.ctr,
1195 r->in.resume_handle,
1196 r->out.totalentries);
1199 /*******************************************************************
1201 ********************************************************************/
1203 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1205 struct sessionid *session_list;
1206 int num_sessions, snum;
1209 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1211 /* strip leading backslashes if any */
1212 while (machine[0] == '\\') {
1213 memmove(machine, &machine[1], strlen(machine));
1216 num_sessions = list_sessions(p->mem_ctx, &session_list);
1218 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1220 status = WERR_ACCESS_DENIED;
1222 /* fail out now if you are not root or not a domain admin */
1224 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1225 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1230 for (snum = 0; snum < num_sessions; snum++) {
1232 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1233 strequal(session_list[snum].remote_machine, machine)) {
1236 ntstat = messaging_send(smbd_messaging_context(),
1237 session_list[snum].pid,
1238 MSG_SHUTDOWN, &data_blob_null);
1240 if (NT_STATUS_IS_OK(ntstat))
1245 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1251 /*******************************************************************
1253 ********************************************************************/
1255 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1257 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1259 if (!pipe_access_check(p)) {
1260 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1261 return WERR_ACCESS_DENIED;
1264 /* Create the list of shares for the response. */
1265 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1266 r->in.resume_handle, r->out.totalentries, True);
1269 /*******************************************************************
1271 ********************************************************************/
1273 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1275 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1277 if (!pipe_access_check(p)) {
1278 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1279 return WERR_ACCESS_DENIED;
1282 /* Create the list of shares for the response. */
1283 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1284 r->in.resume_handle, r->out.totalentries, False);
1287 /*******************************************************************
1289 ********************************************************************/
1291 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1293 const struct share_params *params;
1295 params = get_share_params(p->mem_ctx, r->in.share_name);
1297 if (params != NULL) {
1298 switch (r->in.level) {
1300 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1301 init_srv_share_info_0(p, r->out.info->info0, params);
1304 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1305 init_srv_share_info_1(p, r->out.info->info1, params);
1308 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1309 init_srv_share_info_2(p, r->out.info->info2, params);
1312 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1313 init_srv_share_info_501(p, r->out.info->info501, params);
1316 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1317 init_srv_share_info_502(p, r->out.info->info502, params);
1320 /* here for completeness */
1322 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1323 init_srv_share_info_1004(p, r->out.info->info1004, params);
1326 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1327 init_srv_share_info_1005(p, r->out.info->info1005, params);
1330 /* here for completeness 1006 - 1501 */
1332 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1333 init_srv_share_info_1006(p, r->out.info->info1006,
1337 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1338 init_srv_share_info_1007(p, r->out.info->info1007,
1342 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1343 init_srv_share_info_1501(p, r->out.info->info1501,
1347 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1348 "switch value %d\n", r->in.level));
1349 return WERR_UNKNOWN_LEVEL;
1353 return WERR_INVALID_NAME;
1359 /*******************************************************************
1360 Check a given DOS pathname is valid for a share.
1361 ********************************************************************/
1363 char *valid_share_pathname(char *dos_pathname)
1367 /* Convert any '\' paths to '/' */
1368 unix_format(dos_pathname);
1369 unix_clean_name(dos_pathname);
1371 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1373 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1376 /* Only absolute paths allowed. */
1383 static void setval_helper(struct registry_key *key, const char *name,
1384 const char *value, WERROR *err)
1386 struct registry_value val;
1388 if (!W_ERROR_IS_OK(*err)) {
1394 val.v.sz.str = CONST_DISCARD(char *, value);
1395 val.v.sz.len = strlen(value)+1;
1397 *err = reg_setvalue(key, name, &val);
1400 static WERROR add_share(const char *share_name, const char *path,
1401 const char *comment, uint32 max_connections,
1402 const struct nt_user_token *token,
1405 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1409 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1410 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1411 path, comment, max_connections) == -1) {
1415 DEBUG(10,("add_share: Running [%s]\n", command ));
1417 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1422 if ( (ret = smbrun(command, NULL)) == 0 ) {
1423 /* Tell everyone we updated smb.conf. */
1424 message_send_all(MSG_SMB_CONF_UPDATED,
1425 NULL, 0, False, NULL);
1431 /********* END SeDiskOperatorPrivilege BLOCK *********/
1433 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1437 * No fallback to registry shares, the user did define a add
1438 * share command, so fail here.
1442 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1445 if (lp_registry_shares()) {
1447 struct registry_key *key;
1448 enum winreg_CreateAction action;
1450 TALLOC_CTX *mem_ctx;
1452 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1457 mem_ctx = (TALLOC_CTX *)keyname;
1459 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1460 is_disk_op ? get_root_nt_token():token,
1463 if (action != REG_CREATED_NEW_KEY) {
1464 err = WERR_ALREADY_EXISTS;
1467 if (!W_ERROR_IS_OK(err)) {
1468 TALLOC_FREE(mem_ctx);
1472 setval_helper(key, "path", path, &err);
1473 if ((comment != NULL) && (comment[0] != '\0')) {
1474 setval_helper(key, "comment", comment, &err);
1476 if (max_connections != 0) {
1478 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1479 setval_helper(key, "max connections", tmp, &err);
1482 if (!W_ERROR_IS_OK(err)) {
1484 * Hmmmm. We'd need transactions on the registry to
1485 * get this right....
1487 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1490 TALLOC_FREE(mem_ctx);
1494 return WERR_ACCESS_DENIED;
1497 static WERROR delete_share(const char *sharename,
1498 const struct nt_user_token *token,
1501 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1505 if (asprintf(&command, "%s \"%s\" \"%s\"",
1506 lp_delete_share_cmd(), dyn_CONFIGFILE,
1511 DEBUG(10,("delete_share: Running [%s]\n", command ));
1513 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1518 if ( (ret = smbrun(command, NULL)) == 0 ) {
1519 /* Tell everyone we updated smb.conf. */
1520 message_send_all(MSG_SMB_CONF_UPDATED,
1521 NULL, 0, False, NULL);
1527 /********* END SeDiskOperatorPrivilege BLOCK *********/
1531 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1533 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1536 if (lp_registry_shares()) {
1540 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1545 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1551 return WERR_ACCESS_DENIED;
1554 static WERROR change_share(const char *share_name, const char *path,
1555 const char *comment, uint32 max_connections,
1556 const struct nt_user_token *token,
1559 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1563 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1564 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1565 path, comment, max_connections) == -1) {
1569 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1571 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1576 if ( (ret = smbrun(command, NULL)) == 0 ) {
1577 /* Tell everyone we updated smb.conf. */
1578 message_send_all(MSG_SMB_CONF_UPDATED,
1579 NULL, 0, False, NULL);
1585 /********* END SeDiskOperatorPrivilege BLOCK *********/
1587 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1588 "(%d)\n", command, ret ));
1592 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1595 if (lp_registry_shares()) {
1597 struct registry_key *key;
1599 TALLOC_CTX *mem_ctx;
1601 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1606 mem_ctx = (TALLOC_CTX *)keyname;
1608 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1609 is_disk_op ? get_root_nt_token():token,
1611 if (!W_ERROR_IS_OK(err)) {
1612 TALLOC_FREE(mem_ctx);
1616 setval_helper(key, "path", path, &err);
1618 reg_deletevalue(key, "comment");
1619 if ((comment != NULL) && (comment[0] != '\0')) {
1620 setval_helper(key, "comment", comment, &err);
1623 reg_deletevalue(key, "max connections");
1624 if (max_connections != 0) {
1626 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1627 setval_helper(key, "max connections", tmp, &err);
1630 TALLOC_FREE(mem_ctx);
1634 return WERR_ACCESS_DENIED;
1637 /*******************************************************************
1638 Net share set info. Modify share details.
1639 ********************************************************************/
1641 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1648 SEC_DESC *psd = NULL;
1649 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1650 BOOL is_disk_op = False;
1651 int max_connections = 0;
1652 fstring tmp_share_name;
1654 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1656 if (r->out.parm_error) {
1657 *r->out.parm_error = 0;
1660 if ( strequal(r->in.share_name,"IPC$")
1661 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1662 || strequal(r->in.share_name,"global") )
1664 return WERR_ACCESS_DENIED;
1667 fstrcpy(tmp_share_name, r->in.share_name);
1668 snum = find_service(tmp_share_name);
1670 /* Does this share exist ? */
1672 return WERR_NET_NAME_NOT_FOUND;
1674 /* No change to printer shares. */
1675 if (lp_print_ok(snum))
1676 return WERR_ACCESS_DENIED;
1678 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1681 /* fail out now if you are not root and not a disk op */
1683 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1684 return WERR_ACCESS_DENIED;
1686 switch (r->in.level) {
1688 pstrcpy(pathname, lp_pathname(snum));
1689 pstrcpy(comment, r->in.info.info1->comment);
1690 type = r->in.info.info1->type;
1694 pstrcpy(comment, r->in.info.info2->comment);
1695 pstrcpy(pathname, r->in.info.info2->path);
1696 type = r->in.info.info2->type;
1697 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1698 0 : r->in.info.info2->max_users;
1702 pstrcpy(comment, r->in.info.info502->comment);
1703 pstrcpy(pathname, r->in.info.info502->path);
1704 type = r->in.info.info502->type;
1705 psd = r->in.info.info502->sd;
1706 map_generic_share_sd_bits(psd);
1709 pstrcpy(pathname, lp_pathname(snum));
1710 pstrcpy(comment, r->in.info.info1004->comment);
1711 type = STYPE_DISKTREE;
1714 /* XP re-sets the csc policy even if it wasn't changed by the
1715 user, so we must compare it to see if it's what is set in
1716 smb.conf, so that we can contine other ops like setting
1718 if (((r->in.info.info1005->dfs_flags &
1719 SHARE_1005_CSC_POLICY_MASK) >>
1720 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1723 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1724 "to change csc policy from the network; "
1725 "must be done with smb.conf\n"));
1726 return WERR_ACCESS_DENIED;
1730 return WERR_ACCESS_DENIED;
1732 pstrcpy(pathname, lp_pathname(snum));
1733 pstrcpy(comment, lp_comment(snum));
1734 psd = r->in.info.info1501->sd;
1735 map_generic_share_sd_bits(psd);
1736 type = STYPE_DISKTREE;
1739 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1740 "%d\n", r->in.level));
1741 return WERR_UNKNOWN_LEVEL;
1744 /* We can only modify disk shares. */
1745 if (type != STYPE_DISKTREE)
1746 return WERR_ACCESS_DENIED;
1748 /* Check if the pathname is valid. */
1749 if (!(path = valid_share_pathname( pathname )))
1750 return WERR_OBJECT_PATH_INVALID;
1752 /* Ensure share name, pathname and comment don't contain '"'
1754 string_replace(tmp_share_name, '"', ' ');
1755 string_replace(path, '"', ' ');
1756 string_replace(comment, '"', ' ');
1758 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1759 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1761 /* Only call modify function if something changed. */
1763 if (strcmp(path, lp_pathname(snum))
1764 || strcmp(comment, lp_comment(snum))
1765 || (lp_max_connections(snum) != max_connections) ) {
1768 err = change_share(tmp_share_name, path, comment,
1769 max_connections, p->pipe_user.nt_user_token,
1772 if (!W_ERROR_IS_OK(err)) {
1777 /* Replace SD if changed. */
1782 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1785 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1786 if (!set_share_security(r->in.share_name, psd)) {
1787 DEBUG(0,("_srv_net_share_set_info: Failed to "
1788 "change security info in share %s.\n",
1789 r->in.share_name ));
1794 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1800 /*******************************************************************
1801 Net share add. Call 'add_share_command "sharename" "pathname"
1802 "comment" "max connections = "
1803 ********************************************************************/
1805 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1812 SEC_DESC *psd = NULL;
1813 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1815 uint32 max_connections = 0;
1818 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1820 if (r->out.parm_error) {
1821 *r->out.parm_error = 0;
1824 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1827 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1828 return WERR_ACCESS_DENIED;
1830 switch (r->in.level) {
1832 /* No path. Not enough info in a level 0 to do anything. */
1833 return WERR_ACCESS_DENIED;
1835 /* Not enough info in a level 1 to do anything. */
1836 return WERR_ACCESS_DENIED;
1838 pstrcpy(share_name, r->in.info.info2->name);
1839 pstrcpy(comment, r->in.info.info2->comment);
1840 pstrcpy(pathname, r->in.info.info2->path);
1841 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1842 0 : r->in.info.info2->max_users;
1843 type = r->in.info.info2->type;
1846 /* No path. Not enough info in a level 501 to do anything. */
1847 return WERR_ACCESS_DENIED;
1849 pstrcpy(share_name, r->in.info.info502->name);
1850 pstrcpy(comment, r->in.info.info502->comment);
1851 pstrcpy(pathname, r->in.info.info502->path);
1852 type = r->in.info.info502->type;
1853 psd = r->in.info.info502->sd;
1854 map_generic_share_sd_bits(psd);
1857 /* none of the following contain share names. NetShareAdd
1858 * does not have a separate parameter for the share name */
1864 return WERR_ACCESS_DENIED;
1866 /* DFS only level. */
1867 return WERR_ACCESS_DENIED;
1869 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1871 return WERR_UNKNOWN_LEVEL;
1874 /* check for invalid share names */
1876 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1877 sizeof(share_name) ) ) {
1878 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1880 return WERR_INVALID_NAME;
1883 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1884 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1886 return WERR_ACCESS_DENIED;
1889 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1890 /* Share already exists. */
1891 return WERR_ALREADY_EXISTS;
1894 /* We can only add disk shares. */
1895 if (type != STYPE_DISKTREE)
1896 return WERR_ACCESS_DENIED;
1898 /* Check if the pathname is valid. */
1899 if (!(path = valid_share_pathname( pathname )))
1900 return WERR_OBJECT_PATH_INVALID;
1902 /* Ensure share name, pathname and comment don't contain '"'
1905 string_replace(share_name, '"', ' ');
1906 string_replace(path, '"', ' ');
1907 string_replace(comment, '"', ' ');
1909 err = add_share(share_name, path, comment, max_connections,
1910 p->pipe_user.nt_user_token, is_disk_op);
1912 if (!W_ERROR_IS_OK(err)) {
1917 if (!set_share_security(share_name, psd)) {
1918 DEBUG(0,("_srv_net_share_add: Failed to add security "
1919 "info to share %s.\n", share_name ));
1924 * We don't call reload_services() here, the message will
1925 * cause this to be done before the next packet is read
1926 * from the client. JRA.
1929 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1934 /*******************************************************************
1935 Net share delete. Call "delete share command" with the share name as
1937 ********************************************************************/
1939 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1941 struct share_params *params;
1942 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1946 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1948 if ( strequal(r->in.share_name, "IPC$")
1949 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1950 || strequal(r->in.share_name, "global") )
1952 return WERR_ACCESS_DENIED;
1955 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1956 return WERR_NO_SUCH_SHARE;
1959 /* No change to printer shares. */
1960 if (lp_print_ok(params->service))
1961 return WERR_ACCESS_DENIED;
1963 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1966 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1967 return WERR_ACCESS_DENIED;
1969 err = delete_share(lp_servicename(params->service),
1970 p->pipe_user.nt_user_token, is_disk_op);
1972 if (!W_ERROR_IS_OK(err)) {
1976 /* Delete the SD in the database. */
1977 delete_share_security(params);
1979 lp_killservice(params->service);
1984 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1986 struct srvsvc_NetShareDel s;
1988 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1990 s.in.server_unc = r->in.server_unc;
1991 s.in.share_name = r->in.share_name;
1992 s.in.reserved = r->in.reserved;
1994 return _srvsvc_NetShareDel(p, &s);
1997 /*******************************************************************
1999 ********************************************************************/
2001 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2004 time_t unixdate = time(NULL);
2005 WERROR status = WERR_OK;
2007 /* We do this call first as if we do it *after* the gmtime call
2008 it overwrites the pointed-to values. JRA */
2010 uint32 zone = get_time_zone(unixdate)/60;
2012 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2014 t = gmtime(&unixdate);
2017 r->out.info->elapsed = unixdate;
2018 r->out.info->msecs = 0;
2019 r->out.info->hours = t->tm_hour;
2020 r->out.info->mins = t->tm_min;
2021 r->out.info->secs = t->tm_sec;
2022 r->out.info->hunds = 0;
2023 r->out.info->timezone = zone;
2024 r->out.info->tinterval = 10000;
2025 r->out.info->day = t->tm_mday;
2026 r->out.info->month = t->tm_mon + 1;
2027 r->out.info->year = 1900+t->tm_year;
2028 r->out.info->weekday = t->tm_wday;
2030 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2035 /***********************************************************************************
2036 Win9x NT tools get security descriptor.
2037 ***********************************************************************************/
2039 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2041 SEC_DESC *psd = NULL;
2044 files_struct *fsp = NULL;
2047 connection_struct *conn = NULL;
2048 BOOL became_user = False;
2049 WERROR status = WERR_OK;
2055 /* Null password is ok - we are already an authenticated user... */
2056 null_pw = data_blob_null;
2059 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2063 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2064 status = ntstatus_to_werror(nt_status);
2068 if (!become_user(conn, conn->vuid)) {
2069 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2070 status = WERR_ACCESS_DENIED;
2075 pstrcpy(tmp_file, r->in.file);
2076 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2078 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2079 status = WERR_ACCESS_DENIED;
2083 nt_status = check_name(conn, r->in.file);
2084 if (!NT_STATUS_IS_OK(nt_status)) {
2085 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
2086 status = WERR_ACCESS_DENIED;
2090 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2091 if (!NT_STATUS_IS_OK(nt_status)) {
2092 /* Perhaps it is a directory */
2093 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2094 nt_status = open_directory(conn, r->in.file, &st,
2095 READ_CONTROL_ACCESS,
2096 FILE_SHARE_READ|FILE_SHARE_WRITE,
2099 FILE_ATTRIBUTE_DIRECTORY,
2102 if (!NT_STATUS_IS_OK(nt_status)) {
2103 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
2104 status = WERR_ACCESS_DENIED;
2109 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2112 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
2113 status = WERR_ACCESS_DENIED;
2117 r->out.sd_buf->sd_size= sd_size;
2118 r->out.sd_buf->sd = psd;
2120 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2122 close_file(fsp, NORMAL_CLOSE);
2124 close_cnum(conn, p->pipe_user.vuid);
2130 close_file(fsp, NORMAL_CLOSE);
2137 close_cnum(conn, p->pipe_user.vuid);
2142 /***********************************************************************************
2143 Win9x NT tools set security descriptor.
2144 ***********************************************************************************/
2146 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2150 files_struct *fsp = NULL;
2153 connection_struct *conn = NULL;
2154 BOOL became_user = False;
2155 WERROR status = WERR_OK;
2160 /* Null password is ok - we are already an authenticated user... */
2161 null_pw = data_blob_null;
2164 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2168 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2169 status = ntstatus_to_werror(nt_status);
2173 if (!become_user(conn, conn->vuid)) {
2174 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2175 status = WERR_ACCESS_DENIED;
2180 pstrcpy(tmp_file, r->in.file);
2181 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2182 if (!NT_STATUS_IS_OK(nt_status)) {
2183 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2184 status = WERR_ACCESS_DENIED;
2188 nt_status = check_name(conn, r->in.file);
2189 if (!NT_STATUS_IS_OK(nt_status)) {
2190 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
2191 status = WERR_ACCESS_DENIED;
2196 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2198 if (!NT_STATUS_IS_OK(nt_status)) {
2199 /* Perhaps it is a directory */
2200 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2201 nt_status = open_directory(conn, r->in.file, &st,
2202 FILE_READ_ATTRIBUTES,
2203 FILE_SHARE_READ|FILE_SHARE_WRITE,
2206 FILE_ATTRIBUTE_DIRECTORY,
2209 if (!NT_STATUS_IS_OK(nt_status)) {
2210 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
2211 status = WERR_ACCESS_DENIED;
2216 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2219 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
2220 status = WERR_ACCESS_DENIED;
2224 close_file(fsp, NORMAL_CLOSE);
2226 close_cnum(conn, p->pipe_user.vuid);
2232 close_file(fsp, NORMAL_CLOSE);
2240 close_cnum(conn, p->pipe_user.vuid);
2246 /***********************************************************************************
2247 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2248 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2249 These disks would the disks listed by this function.
2250 Users could then create shares relative to these disks. Watch out for moving these disks around.
2251 "Nigel Williams" <nigel@veritas.com>.
2252 ***********************************************************************************/
2254 static const char *server_disks[] = {"C:"};
2256 static uint32 get_server_disk_count(void)
2258 return sizeof(server_disks)/sizeof(server_disks[0]);
2261 static uint32 init_server_disk_enum(uint32 *resume)
2263 uint32 server_disk_count = get_server_disk_count();
2265 /*resume can be an offset into the list for now*/
2267 if(*resume & 0x80000000)
2270 if(*resume > server_disk_count)
2271 *resume = server_disk_count;
2273 return server_disk_count - *resume;
2276 static const char *next_server_disk_enum(uint32 *resume)
2280 if(init_server_disk_enum(resume) == 0)
2283 disk = server_disks[*resume];
2287 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2292 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2295 const char *disk_name;
2297 WERROR status = WERR_OK;
2299 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2300 r->out.info->count = 0;
2302 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2306 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2308 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2310 r->out.info->count++;
2311 (*r->out.totalentries)++;
2313 /*copy disk name into a unicode string*/
2315 r->out.info->disks[i].disk = disk_name;
2318 /* add a terminating null string. Is this there if there is more data to come? */
2320 r->out.info->count++;
2321 (*r->out.totalentries)++;
2323 r->out.info->disks[i].disk = "";
2328 /********************************************************************
2329 ********************************************************************/
2331 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2335 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2336 return WERR_INVALID_PARAM;
2339 switch ( r->in.name_type ) {
2341 len = strlen_m(r->in.name);
2343 if ((r->in.flags == 0x0) && (len > 81)) {
2344 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2345 return WERR_INVALID_NAME;
2347 if ((r->in.flags == 0x80000000) && (len > 13)) {
2348 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2349 return WERR_INVALID_NAME;
2352 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2353 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2354 return WERR_INVALID_NAME;
2359 return WERR_UNKNOWN_LEVEL;
2366 /********************************************************************
2367 ********************************************************************/
2369 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2371 return WERR_ACCESS_DENIED;
2374 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2376 p->rng_fault_state = True;
2377 return WERR_NOT_SUPPORTED;
2380 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2382 p->rng_fault_state = True;
2383 return WERR_NOT_SUPPORTED;
2386 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2388 p->rng_fault_state = True;
2389 return WERR_NOT_SUPPORTED;
2392 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2394 p->rng_fault_state = True;
2395 return WERR_NOT_SUPPORTED;
2398 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2400 p->rng_fault_state = True;
2401 return WERR_NOT_SUPPORTED;
2404 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2406 p->rng_fault_state = True;
2407 return WERR_NOT_SUPPORTED;
2410 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2412 p->rng_fault_state = True;
2413 return WERR_NOT_SUPPORTED;
2416 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2418 p->rng_fault_state = True;
2419 return WERR_NOT_SUPPORTED;
2422 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2424 p->rng_fault_state = True;
2425 return WERR_NOT_SUPPORTED;
2428 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2430 p->rng_fault_state = True;
2431 return WERR_NOT_SUPPORTED;
2434 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2436 p->rng_fault_state = True;
2437 return WERR_NOT_SUPPORTED;
2440 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2442 p->rng_fault_state = True;
2443 return WERR_NOT_SUPPORTED;
2446 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2448 p->rng_fault_state = True;
2449 return WERR_NOT_SUPPORTED;
2452 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2454 p->rng_fault_state = True;
2455 return WERR_NOT_SUPPORTED;
2458 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2460 p->rng_fault_state = True;
2461 return WERR_NOT_SUPPORTED;
2464 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2466 p->rng_fault_state = True;
2467 return WERR_NOT_SUPPORTED;
2470 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2472 p->rng_fault_state = True;
2473 return WERR_NOT_SUPPORTED;
2476 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2478 p->rng_fault_state = True;
2479 return WERR_NOT_SUPPORTED;
2482 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2484 p->rng_fault_state = True;
2485 return WERR_NOT_SUPPORTED;
2488 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2490 p->rng_fault_state = True;
2491 return WERR_NOT_SUPPORTED;
2494 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2496 p->rng_fault_state = True;
2497 return WERR_NOT_SUPPORTED;
2500 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2502 p->rng_fault_state = True;
2503 return WERR_NOT_SUPPORTED;
2506 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2508 p->rng_fault_state = True;
2509 return WERR_NOT_SUPPORTED;
2512 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2514 p->rng_fault_state = True;
2515 return WERR_NOT_SUPPORTED;
2518 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2520 p->rng_fault_state = True;
2521 return WERR_NOT_SUPPORTED;
2524 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2526 p->rng_fault_state = True;
2527 return WERR_NOT_SUPPORTED;
2530 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2532 p->rng_fault_state = True;
2533 return WERR_NOT_SUPPORTED;
2536 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2538 p->rng_fault_state = True;
2539 return WERR_NOT_SUPPORTED;
2542 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2544 p->rng_fault_state = True;
2545 return WERR_NOT_SUPPORTED;
2548 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2550 p->rng_fault_state = True;
2551 return WERR_NOT_SUPPORTED;
2554 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2556 p->rng_fault_state = True;
2557 return WERR_NOT_SUPPORTED;
2560 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2562 p->rng_fault_state = True;
2563 return WERR_NOT_SUPPORTED;
2566 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2568 p->rng_fault_state = True;
2569 return WERR_NOT_SUPPORTED;
2572 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2574 p->rng_fault_state = True;
2575 return WERR_NOT_SUPPORTED;
2578 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2580 p->rng_fault_state = True;
2581 return WERR_NOT_SUPPORTED;