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 fenum->info[i].user = uidtoname( prec.uid );
84 fenum->info[i].path = fullpath;
92 /*******************************************************************
93 ********************************************************************/
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
96 uint32 *count, uint32 *resume )
98 struct file_enum_count fenum;
99 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
102 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103 return WERR_ACCESS_DENIED;
108 fenum.count = *count;
110 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112 tdb_errorstr(conn_tdb) ));
117 *count = fenum.count;
121 /*******************************************************************
122 ********************************************************************/
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
127 static void enum_file_fn( const struct share_mode_entry *e,
128 const char *sharepath, const char *fname,
131 struct file_enum_count *fenum = &f_enum_cnt;
133 /* If the pid was not found delete the entry from connections.tdb */
135 if ( process_exists(e->pid) ) {
136 struct srvsvc_NetFileInfo3 *f;
137 int i = fenum->count;
139 struct byte_range_lock *brl;
144 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
146 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
151 /* need to count the number of locks on a file */
155 fsp.inode = e->inode;
157 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158 num_locks = brl->num_locks;
162 if ( strcmp( fname, "." ) == 0 ) {
163 pstr_sprintf( fullpath, "C:%s", sharepath );
165 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
167 string_replace( fullpath, '/', '\\' );
169 /* mask out create (what ever that is) */
170 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
172 fenum->info[i].fid = e->share_file_id;
173 fenum->info[i].permissions = permissions;
174 fenum->info[i].num_locks = num_locks;
175 fenum->info[i].user = uidtoname(e->uid);
176 fenum->info[i].path = fullpath;
185 /*******************************************************************
186 ********************************************************************/
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
189 uint32 *count, uint32 *resume )
191 f_enum_cnt.ctx = ctx;
192 f_enum_cnt.count = *count;
193 f_enum_cnt.info = *info;
195 share_mode_forall( enum_file_fn, NULL );
197 *info = f_enum_cnt.info;
198 *count = f_enum_cnt.count;
203 /*******************************************************************
204 Utility function to get the 'type' of a share from a share definition.
205 ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
208 char *net_name = lp_servicename(params->service);
209 int len_net_name = strlen(net_name);
211 /* work out the share type */
212 uint32 type = STYPE_DISKTREE;
214 if (lp_print_ok(params->service))
216 if (strequal(lp_fstype(params->service), "IPC"))
218 if (net_name[len_net_name] == '$')
219 type |= STYPE_HIDDEN;
224 /*******************************************************************
225 Fill in a share info level 0 structure.
226 ********************************************************************/
228 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
229 const struct share_params *params)
231 sh0->name = lp_servicename(params->service);
234 /*******************************************************************
235 Fill in a share info level 1 structure.
236 ********************************************************************/
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239 const struct share_params *params)
241 connection_struct *conn = p->conn;
243 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244 conn->user, conn->connectpath, conn->gid,
245 get_current_username(),
246 current_user_info.domain,
247 lp_comment(params->service));
249 sh1->name = lp_servicename(params->service);
250 sh1->type = get_share_type(params);
253 /*******************************************************************
254 Fill in a share info level 2 structure.
255 ********************************************************************/
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258 const struct share_params *params)
260 connection_struct *conn = p->conn;
263 int max_connections = lp_max_connections(params->service);
264 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
266 char *net_name = lp_servicename(params->service);
268 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269 conn->user, conn->connectpath, conn->gid,
270 get_current_username(),
271 current_user_info.domain,
272 lp_comment(params->service));
273 path = talloc_asprintf(p->mem_ctx, "C:%s",
274 lp_pathname(params->service));
277 * Change / to \\ so that win2k will see it as a valid path. This was
278 * added to enable use of browsing in win2k add share dialog.
281 string_replace(path, '/', '\\');
283 count = count_current_connections( net_name, False );
284 sh2->name = net_name;
285 sh2->type = get_share_type(params);
286 sh2->comment = remark;
287 sh2->permissions = 0;
288 sh2->max_users = max_uses;
289 sh2->current_users = count;
294 /*******************************************************************
295 Map any generic bits to file specific bits.
296 ********************************************************************/
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
301 SEC_ACL *ps_dacl = NULL;
310 for (i = 0; i < ps_dacl->num_aces; i++) {
311 SEC_ACE *psa = &ps_dacl->aces[i];
312 uint32 orig_mask = psa->access_mask;
314 se_map_generic(&psa->access_mask, &file_generic_mapping);
315 psa->access_mask |= orig_mask;
319 /*******************************************************************
320 Fill in a share info level 501 structure.
321 ********************************************************************/
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324 const struct share_params *params)
326 connection_struct *conn = p->conn;
328 const char *net_name = lp_servicename(params->service);
330 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331 conn->user, conn->connectpath, conn->gid,
332 get_current_username(),
333 current_user_info.domain,
334 lp_comment(params->service));
337 sh501->name = net_name;
338 sh501->type = get_share_type(params);
339 sh501->comment = remark;
340 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
343 /*******************************************************************
344 Fill in a share info level 502 structure.
345 ********************************************************************/
347 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
348 const struct share_params *params)
350 int max_connections = lp_max_connections(params->service);
351 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352 connection_struct *conn = p->conn;
359 TALLOC_CTX *ctx = p->mem_ctx;
364 net_name = lp_servicename(params->service);
365 count = count_current_connections( net_name, False );
367 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368 conn->user, conn->connectpath, conn->gid,
369 get_current_username(),
370 current_user_info.domain,
371 lp_comment(params->service));
373 path = talloc_asprintf(p->mem_ctx, "C:%s",
374 lp_pathname(params->service));
377 * Change / to \\ so that win2k will see it as a valid path. This was
378 * added to enable use of browsing in win2k add share dialog.
381 string_replace(path, '/', '\\');
383 sd = get_share_security(ctx, lp_servicename(params->service),
386 sh502->name = net_name;
387 sh502->type = get_share_type(params);
388 sh502->comment = remark;
390 sh502->password = "";
392 sh502->permissions = 0;
393 sh502->max_users = max_uses;
394 sh502->current_users = count;
398 /***************************************************************************
399 Fill in a share info level 1004 structure.
400 ***************************************************************************/
402 static void init_srv_share_info_1004(pipes_struct *p,
403 struct srvsvc_NetShareInfo1004* sh1004,
404 const struct share_params *params)
406 connection_struct *conn = p->conn;
409 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410 conn->user, conn->connectpath, conn->gid,
411 get_current_username(),
412 current_user_info.domain,
413 lp_comment(params->service));
415 ZERO_STRUCTP(sh1004);
417 sh1004->comment = remark;
420 /***************************************************************************
421 Fill in a share info level 1005 structure.
422 ***************************************************************************/
424 static void init_srv_share_info_1005(pipes_struct *p,
425 struct srvsvc_NetShareInfo1005* sh1005,
426 const struct share_params *params)
428 sh1005->dfs_flags = 0;
430 if(lp_host_msdfs() && lp_msdfs_root(params->service))
432 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
434 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
436 /***************************************************************************
437 Fill in a share info level 1006 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1006(pipes_struct *p,
441 struct srvsvc_NetShareInfo1006* sh1006,
442 const struct share_params *params)
444 sh1006->max_users = -1;
447 /***************************************************************************
448 Fill in a share info level 1007 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1007(pipes_struct *p,
452 struct srvsvc_NetShareInfo1007* sh1007,
453 const struct share_params *params)
457 ZERO_STRUCTP(sh1007);
459 sh1007->flags = flags;
460 sh1007->alternate_directory_name = "";
463 /*******************************************************************
464 Fill in a share info level 1501 structure.
465 ********************************************************************/
467 static void init_srv_share_info_1501(pipes_struct *p,
468 struct sec_desc_buf *sh1501,
469 const struct share_params *params)
473 TALLOC_CTX *ctx = p->mem_ctx;
475 ZERO_STRUCTP(sh1501);
477 sd = get_share_security(ctx, lp_servicename(params->service),
483 /*******************************************************************
484 True if it ends in '$'.
485 ********************************************************************/
487 static BOOL is_hidden_share(const struct share_params *params)
489 const char *net_name = lp_servicename(params->service);
491 return (net_name[strlen(net_name) - 1] == '$');
494 /*******************************************************************
495 Fill in a share info structure.
496 ********************************************************************/
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499 union srvsvc_NetShareCtr *ctr,
500 uint32 info_level, uint32 *resume_hnd,
501 uint32 *total_entries, BOOL all_shares)
503 TALLOC_CTX *ctx = p->mem_ctx;
504 struct share_iterator *shares;
505 struct share_params *share;
506 WERROR result = WERR_NOMEM;
508 DEBUG(5,("init_srv_share_info_ctr\n"));
516 /* Ensure all the usershares are loaded. */
518 load_usershare_shares();
519 load_registry_shares();
524 if (!(shares = share_list_all(ctx))) {
525 DEBUG(5, ("Could not list shares\n"));
526 return WERR_ACCESS_DENIED;
529 switch (info_level) {
531 if (!(ctr->ctr0 = talloc_zero(
532 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
537 if (!(ctr->ctr1 = talloc_zero(
538 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
543 if (!(ctr->ctr2 = talloc_zero(
544 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
549 if (!(ctr->ctr501 = talloc_zero(
550 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
555 if (!(ctr->ctr502 = talloc_zero(
556 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
561 if (!(ctr->ctr1004 = talloc_zero(
562 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
567 if (!(ctr->ctr1005 = talloc_zero(
568 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
573 if (!(ctr->ctr1006 = talloc_zero(
574 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
579 if (!(ctr->ctr1007 = talloc_zero(
580 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
585 if (!(ctr->ctr1501 = talloc_zero(
586 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
591 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
592 "value %d\n", info_level));
593 return WERR_UNKNOWN_LEVEL;
596 while ((share = next_share(shares)) != NULL) {
597 if (!lp_browseable(share->service)) {
600 if (!all_shares && is_hidden_share(share)) {
604 switch (info_level) {
607 struct srvsvc_NetShareInfo0 i;
608 init_srv_share_info_0(p, &i, share);
609 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
610 &ctr->ctr0->array, &ctr->ctr0->count);
611 if (ctr->ctr0->array == NULL) {
614 *total_entries = ctr->ctr0->count;
620 struct srvsvc_NetShareInfo1 i;
621 init_srv_share_info_1(p, &i, share);
622 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
623 &ctr->ctr1->array, &ctr->ctr1->count);
624 if (ctr->ctr1->array == NULL) {
627 *total_entries = ctr->ctr1->count;
633 struct srvsvc_NetShareInfo2 i;
634 init_srv_share_info_2(p, &i, share);
635 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
636 &ctr->ctr2->array, &ctr->ctr2->count);
637 if (ctr->ctr2->array == NULL) {
640 *total_entries = ctr->ctr2->count;
646 struct srvsvc_NetShareInfo501 i;
647 init_srv_share_info_501(p, &i, share);
648 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
649 &ctr->ctr501->array, &ctr->ctr501->count);
650 if (ctr->ctr501->array == NULL) {
653 *total_entries = ctr->ctr501->count;
659 struct srvsvc_NetShareInfo502 i;
660 init_srv_share_info_502(p, &i, share);
661 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
662 &ctr->ctr502->array, &ctr->ctr502->count);
663 if (ctr->ctr502->array == NULL) {
666 *total_entries = ctr->ctr502->count;
670 /* here for completeness but not currently used with enum
675 struct srvsvc_NetShareInfo1004 i;
676 init_srv_share_info_1004(p, &i, share);
677 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
678 &ctr->ctr1004->array, &ctr->ctr1004->count);
679 if (ctr->ctr1004->array == NULL) {
682 *total_entries = ctr->ctr1004->count;
688 struct srvsvc_NetShareInfo1005 i;
689 init_srv_share_info_1005(p, &i, share);
690 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
691 &ctr->ctr1005->array, &ctr->ctr1005->count);
692 if (ctr->ctr1005->array == NULL) {
695 *total_entries = ctr->ctr1005->count;
701 struct srvsvc_NetShareInfo1006 i;
702 init_srv_share_info_1006(p, &i, share);
703 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
704 &ctr->ctr1006->array, &ctr->ctr1006->count);
705 if (ctr->ctr1006->array == NULL) {
708 *total_entries = ctr->ctr1006->count;
714 struct srvsvc_NetShareInfo1007 i;
715 init_srv_share_info_1007(p, &i, share);
716 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
717 &ctr->ctr1007->array, &ctr->ctr1007->count);
718 if (ctr->ctr1007->array == NULL) {
721 *total_entries = ctr->ctr1007->count;
727 struct sec_desc_buf i;
728 init_srv_share_info_1501(p, &i, share);
729 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
730 &ctr->ctr1501->array, &ctr->ctr1501->count);
731 if (ctr->ctr1501->array == NULL) {
734 *total_entries = ctr->ctr1501->count;
748 /*******************************************************************
749 fill in a sess info level 0 structure.
750 ********************************************************************/
752 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
754 struct sessionid *session_list;
755 uint32 num_entries = 0;
756 (*stot) = list_sessions(&session_list);
762 SAFE_FREE(session_list);
766 DEBUG(5,("init_srv_sess_0_ss0\n"));
768 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
771 for (; (*snum) < (*stot); (*snum)++) {
772 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
776 ss0->count = num_entries;
778 if ((*snum) >= (*stot)) {
786 SAFE_FREE(session_list);
789 /*******************************************************************
790 ********************************************************************/
792 static void sess_file_fn( const struct share_mode_entry *e,
793 const char *sharepath, const char *fname,
796 struct sess_file_count *sess = (struct sess_file_count *)private_data;
798 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
805 /*******************************************************************
806 ********************************************************************/
808 static int net_count_files( uid_t uid, pid_t pid )
810 struct sess_file_count s_file_cnt;
812 s_file_cnt.count = 0;
813 s_file_cnt.uid = uid;
814 s_file_cnt.pid = pid;
816 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
818 return s_file_cnt.count;
821 /*******************************************************************
822 fill in a sess info level 1 structure.
823 ********************************************************************/
825 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
827 struct sessionid *session_list;
828 uint32 num_entries = 0;
829 time_t now = time(NULL);
846 (*stot) = list_sessions(&session_list);
848 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
850 for (; (*snum) < (*stot); (*snum)++) {
853 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
857 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
858 session_list[*snum].username));
862 connect_time = (uint32)(now - session_list[*snum].connect_start);
863 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
864 guest = strequal( session_list[*snum].username, lp_guestaccount() );
866 ss1->array[num_entries].client = session_list[*snum].remote_machine;
867 ss1->array[num_entries].user = session_list[*snum].username;
868 ss1->array[num_entries].num_open = num_files;
869 ss1->array[num_entries].time = connect_time;
870 ss1->array[num_entries].idle_time = 0;
871 ss1->array[num_entries].user_flags = guest;
876 ss1->count = num_entries;
878 if ((*snum) >= (*stot)) {
882 SAFE_FREE(session_list);
885 /*******************************************************************
886 makes a SRV_R_NET_SESS_ENUM structure.
887 ********************************************************************/
889 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
890 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
892 WERROR status = WERR_OK;
893 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
895 switch (switch_value) {
897 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
898 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
901 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
902 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
905 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
906 if (resume_hnd != NULL)
908 (*total_entries) = 0;
910 status = WERR_UNKNOWN_LEVEL;
917 /*******************************************************************
918 fill in a conn info level 0 structure.
919 ********************************************************************/
921 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
923 uint32 num_entries = 0;
932 DEBUG(5,("init_srv_conn_0_ss0\n"));
935 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
936 for (; (*snum) < (*stot); (*snum)++) {
938 ss0->array[num_entries].conn_id = (*stot);
940 /* move on to creating next connection */
941 /* move on to creating next conn */
945 ss0->count = num_entries;
947 if ((*snum) >= (*stot)) {
959 /*******************************************************************
960 fill in a conn info level 1 structure.
961 ********************************************************************/
963 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
965 uint32 num_entries = 0;
974 DEBUG(5,("init_srv_conn_1_ss1\n"));
977 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
978 for (; (*snum) < (*stot); (*snum)++) {
979 ss1->array[num_entries].conn_id = (*stot);
980 ss1->array[num_entries].conn_type = 0x3;
981 ss1->array[num_entries].num_open = 1;
982 ss1->array[num_entries].num_users = 1;
983 ss1->array[num_entries].conn_time = 3;
984 ss1->array[num_entries].user = "dummy_user";
985 ss1->array[num_entries].share = "IPC$";
987 /* move on to creating next connection */
988 /* move on to creating next conn */
992 ss1->count = num_entries;
994 if ((*snum) >= (*stot)) {
1006 /*******************************************************************
1007 makes a SRV_R_NET_CONN_ENUM structure.
1008 ********************************************************************/
1010 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1011 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1013 WERROR status = WERR_OK;
1014 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1016 switch (switch_value) {
1018 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1021 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1024 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1027 (*total_entries) = 0;
1028 status = WERR_UNKNOWN_LEVEL;
1035 /*******************************************************************
1036 makes a SRV_R_NET_FILE_ENUM structure.
1037 ********************************************************************/
1039 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1041 TALLOC_CTX *ctx = get_talloc_ctx();
1044 /* TODO -- Windows enumerates
1046 (c) open directories and files */
1048 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1050 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1051 if ( !W_ERROR_IS_OK(status))
1054 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1055 if ( !W_ERROR_IS_OK(status))
1058 ctr->ctr3->count = *num_entries;
1063 /*******************************************************************
1064 *******************************************************************/
1066 WERROR _srvsvc_NetFileEnum(pipes_struct *p, const char *server_unc, const char *path, const char *user, uint32_t *level, union srvsvc_NetFileCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1070 return net_file_enum_3(p, ctr, resume_handle, totalentries );
1072 return WERR_UNKNOWN_LEVEL;
1078 /*******************************************************************
1080 ********************************************************************/
1082 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1084 WERROR status = WERR_OK;
1088 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1090 if (!pipe_access_check(p)) {
1091 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1092 return WERR_ACCESS_DENIED;
1097 /* Technically level 102 should only be available to
1098 Administrators but there isn't anything super-secret
1099 here, as most of it is made up. */
1102 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1104 info->info102->platform_id = 500;
1105 info->info102->version_major = lp_major_announce_version();
1106 info->info102->version_minor = lp_minor_announce_version();
1107 info->info102->server_name = global_myname();
1108 info->info102->server_type = lp_default_server_announce();
1109 info->info102->userpath = "C:\\";
1110 info->info102->licenses = 10000;
1111 info->info102->anndelta = 3000;
1112 info->info102->disc = 0xf;
1113 info->info102->users = 0xffffffff;
1114 info->info102->hidden = 0;
1115 info->info102->announce = 240;
1116 info->info102->comment = lp_serverstring();
1119 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1120 info->info101->platform_id = 500;
1121 info->info101->server_name = global_myname();
1122 info->info101->version_major = lp_major_announce_version();
1123 info->info101->version_minor = lp_minor_announce_version();
1124 info->info101->server_type = lp_default_server_announce();
1125 info->info101->comment = lp_serverstring();
1128 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1129 info->info100->platform_id = 500;
1130 info->info100->server_name = global_myname();
1133 return WERR_UNKNOWN_LEVEL;
1137 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1142 /*******************************************************************
1144 ********************************************************************/
1146 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1148 /* Set up the net server set info structure. */
1153 /*******************************************************************
1155 ********************************************************************/
1157 WERROR _srvsvc_NetConnEnum(pipes_struct *p, const char *server_unc, const char *path, uint32_t *level, union srvsvc_NetConnCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1159 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1164 return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1167 /*******************************************************************
1169 ********************************************************************/
1171 WERROR _srvsvc_NetSessEnum(pipes_struct *p, const char *server_unc, const char *client, const char *user, uint32_t *level, union srvsvc_NetSessCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1173 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1178 return init_srv_sess_info_ctr(p, ctr,
1184 /*******************************************************************
1186 ********************************************************************/
1188 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1190 struct sessionid *session_list;
1191 int num_sessions, snum;
1194 char *machine = talloc_strdup(p->mem_ctx, server_unc);
1196 /* strip leading backslashes if any */
1197 while (machine[0] == '\\') {
1198 memmove(machine, &machine[1], strlen(machine));
1201 num_sessions = list_sessions(&session_list);
1203 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1205 status = WERR_ACCESS_DENIED;
1207 /* fail out now if you are not root or not a domain admin */
1209 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1210 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1215 for (snum = 0; snum < num_sessions; snum++) {
1217 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1218 strequal(session_list[snum].remote_machine, machine)) {
1220 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1225 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1229 SAFE_FREE(session_list);
1234 /*******************************************************************
1236 ********************************************************************/
1238 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1240 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1242 if (!pipe_access_check(p)) {
1243 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1244 return WERR_ACCESS_DENIED;
1247 /* Create the list of shares for the response. */
1248 return init_srv_share_info_ctr(p, ctr, *level,
1249 resume_handle, totalentries, True);
1252 /*******************************************************************
1254 ********************************************************************/
1256 WERROR _srvsvc_NetShareEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1258 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1260 if (!pipe_access_check(p)) {
1261 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1262 return WERR_ACCESS_DENIED;
1265 /* Create the list of shares for the response. */
1266 return init_srv_share_info_ctr(p, ctr, *level,
1267 resume_handle, totalentries, False);
1270 /*******************************************************************
1272 ********************************************************************/
1274 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1276 const struct share_params *params;
1278 params = get_share_params(p->mem_ctx, share_name);
1280 if (params != NULL) {
1283 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1284 init_srv_share_info_0(p, info->info0,
1288 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1289 init_srv_share_info_1(p, info->info1,
1293 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1294 init_srv_share_info_2(p, info->info2,
1298 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1299 init_srv_share_info_501(p, info->info501,
1303 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1304 init_srv_share_info_502(p, info->info502,
1308 /* here for completeness */
1310 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1311 init_srv_share_info_1004(p, info->info1004,
1315 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1316 init_srv_share_info_1005(p, info->info1005,
1320 /* here for completeness 1006 - 1501 */
1322 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1323 init_srv_share_info_1006(p, info->info1006,
1327 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1328 init_srv_share_info_1007(p, info->info1007,
1332 info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1333 init_srv_share_info_1501(p, info->info1501,
1337 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1338 "switch value %d\n", level));
1339 return WERR_UNKNOWN_LEVEL;
1343 return WERR_INVALID_NAME;
1349 /*******************************************************************
1350 Check a given DOS pathname is valid for a share.
1351 ********************************************************************/
1353 char *valid_share_pathname(char *dos_pathname)
1357 /* Convert any '\' paths to '/' */
1358 unix_format(dos_pathname);
1359 unix_clean_name(dos_pathname);
1361 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1363 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1366 /* Only absolute paths allowed. */
1373 /*******************************************************************
1374 Net share set info. Modify share details.
1375 ********************************************************************/
1377 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1386 SEC_DESC *psd = NULL;
1387 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1388 BOOL is_disk_op = False;
1389 int max_connections = 0;
1390 fstring tmp_share_name;
1392 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1396 if ( strequal(share_name,"IPC$")
1397 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1398 || strequal(share_name,"global") )
1400 return WERR_ACCESS_DENIED;
1403 fstrcpy(tmp_share_name, share_name);
1404 snum = find_service(tmp_share_name);
1406 /* Does this share exist ? */
1408 return WERR_NET_NAME_NOT_FOUND;
1410 /* No change to printer shares. */
1411 if (lp_print_ok(snum))
1412 return WERR_ACCESS_DENIED;
1414 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1416 /* fail out now if you are not root and not a disk op */
1418 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1419 return WERR_ACCESS_DENIED;
1423 pstrcpy(pathname, lp_pathname(snum));
1424 pstrcpy(comment, info.info1->comment);
1425 type = info.info1->type;
1429 pstrcpy(comment, info.info2->comment);
1430 pstrcpy(pathname, info.info2->path);
1431 type = info.info2->type;
1432 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1436 /* not supported on set but here for completeness */
1438 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1439 type = q_u->info.share.info501.info_501.type;
1444 pstrcpy(comment, info.info502->comment);
1445 pstrcpy(pathname, info.info502->path);
1446 type = info.info502->type;
1447 psd = info.info502->sd;
1448 map_generic_share_sd_bits(psd);
1451 pstrcpy(pathname, lp_pathname(snum));
1452 pstrcpy(comment, info.info1004->comment);
1453 type = STYPE_DISKTREE;
1456 /* XP re-sets the csc policy even if it wasn't changed by the
1457 user, so we must compare it to see if it's what is set in
1458 smb.conf, so that we can contine other ops like setting
1460 if (((info.info1005->dfs_flags &
1461 SHARE_1005_CSC_POLICY_MASK) >>
1462 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1465 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1466 return WERR_ACCESS_DENIED;
1470 return WERR_ACCESS_DENIED;
1472 pstrcpy(pathname, lp_pathname(snum));
1473 pstrcpy(comment, lp_comment(snum));
1474 psd = info.info1501->sd;
1475 map_generic_share_sd_bits(psd);
1476 type = STYPE_DISKTREE;
1479 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1480 return WERR_UNKNOWN_LEVEL;
1483 /* We can only modify disk shares. */
1484 if (type != STYPE_DISKTREE)
1485 return WERR_ACCESS_DENIED;
1487 /* Check if the pathname is valid. */
1488 if (!(path = valid_share_pathname( pathname )))
1489 return WERR_OBJECT_PATH_INVALID;
1491 /* Ensure share name, pathname and comment don't contain '"' characters. */
1492 string_replace(tmp_share_name, '"', ' ');
1493 string_replace(path, '"', ' ');
1494 string_replace(comment, '"', ' ');
1496 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1497 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1499 /* Only call modify function if something changed. */
1501 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1502 || (lp_max_connections(snum) != max_connections) )
1504 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1505 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1506 return WERR_ACCESS_DENIED;
1509 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1510 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1512 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1514 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1519 if ( (ret = smbrun(command, NULL)) == 0 ) {
1520 /* Tell everyone we updated smb.conf. */
1521 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1527 /********* END SeDiskOperatorPrivilege BLOCK *********/
1529 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1532 return WERR_ACCESS_DENIED;
1534 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1537 /* Replace SD if changed. */
1542 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1545 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1546 if (!set_share_security(share_name, psd))
1547 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1552 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1557 /*******************************************************************
1558 Net share add. Call 'add_share_command "sharename" "pathname"
1559 "comment" "max connections = "
1560 ********************************************************************/
1562 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1572 SEC_DESC *psd = NULL;
1573 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1575 int max_connections = 0;
1577 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1581 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1583 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1584 return WERR_ACCESS_DENIED;
1586 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1587 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1588 return WERR_ACCESS_DENIED;
1593 /* No path. Not enough info in a level 0 to do anything. */
1594 return WERR_ACCESS_DENIED;
1596 /* Not enough info in a level 1 to do anything. */
1597 return WERR_ACCESS_DENIED;
1599 pstrcpy(share_name, info.info2->name);
1600 pstrcpy(comment, info.info2->comment);
1601 pstrcpy(pathname, info.info2->path);
1602 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1603 type = info.info2->type;
1606 /* No path. Not enough info in a level 501 to do anything. */
1607 return WERR_ACCESS_DENIED;
1609 pstrcpy(share_name, info.info502->name);
1610 pstrcpy(comment, info.info502->comment);
1611 pstrcpy(pathname, info.info502->path);
1612 type = info.info502->type;
1613 psd = info.info502->sd;
1614 map_generic_share_sd_bits(psd);
1617 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1623 return WERR_ACCESS_DENIED;
1625 /* DFS only level. */
1626 return WERR_ACCESS_DENIED;
1628 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1629 return WERR_UNKNOWN_LEVEL;
1632 /* check for invalid share names */
1634 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1635 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1636 return WERR_INVALID_NAME;
1639 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1640 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1642 return WERR_ACCESS_DENIED;
1645 snum = find_service(share_name);
1647 /* Share already exists. */
1649 return WERR_ALREADY_EXISTS;
1651 /* We can only add disk shares. */
1652 if (type != STYPE_DISKTREE)
1653 return WERR_ACCESS_DENIED;
1655 /* Check if the pathname is valid. */
1656 if (!(path = valid_share_pathname( pathname )))
1657 return WERR_OBJECT_PATH_INVALID;
1659 /* Ensure share name, pathname and comment don't contain '"' characters. */
1660 string_replace(share_name, '"', ' ');
1661 string_replace(path, '"', ' ');
1662 string_replace(comment, '"', ' ');
1664 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1672 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1674 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1679 if ( (ret = smbrun(command, NULL)) == 0 ) {
1680 /* Tell everyone we updated smb.conf. */
1681 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1687 /********* END SeDiskOperatorPrivilege BLOCK *********/
1689 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1692 return WERR_ACCESS_DENIED;
1695 if (!set_share_security(share_name, psd)) {
1696 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1701 * We don't call reload_services() here, the message will
1702 * cause this to be done before the next packet is read
1703 * from the client. JRA.
1706 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1711 /*******************************************************************
1712 Net share delete. Call "delete share command" with the share name as
1714 ********************************************************************/
1716 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1720 struct share_params *params;
1721 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1724 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1726 if ( strequal(share_name,"IPC$")
1727 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1728 || strequal(share_name,"global") )
1730 return WERR_ACCESS_DENIED;
1733 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1734 return WERR_NO_SUCH_SHARE;
1737 /* No change to printer shares. */
1738 if (lp_print_ok(params->service))
1739 return WERR_ACCESS_DENIED;
1741 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1743 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1744 return WERR_ACCESS_DENIED;
1746 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1747 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1748 return WERR_ACCESS_DENIED;
1751 if (asprintf(&command, "%s \"%s\" \"%s\"",
1752 lp_delete_share_cmd(), dyn_CONFIGFILE,
1753 lp_servicename(params->service)) == -1) {
1757 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1759 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1764 if ( (ret = smbrun(command, NULL)) == 0 ) {
1765 /* Tell everyone we updated smb.conf. */
1766 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1774 /********* END SeDiskOperatorPrivilege BLOCK *********/
1776 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1779 return WERR_ACCESS_DENIED;
1781 /* Delete the SD in the database. */
1782 delete_share_security(params);
1784 lp_killservice(params->service);
1789 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1791 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1793 return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1796 /*******************************************************************
1798 ********************************************************************/
1800 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1803 time_t unixdate = time(NULL);
1804 WERROR status = WERR_OK;
1806 /* We do this call first as if we do it *after* the gmtime call
1807 it overwrites the pointed-to values. JRA */
1809 uint32 zone = get_time_zone(unixdate)/60;
1811 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1813 t = gmtime(&unixdate);
1816 tod->elapsed = unixdate;
1818 tod->hours = t->tm_hour;
1819 tod->mins = t->tm_min;
1820 tod->secs = t->tm_sec;
1822 tod->timezone = zone;
1823 tod->tinterval = 10000;
1824 tod->day = t->tm_mday;
1825 tod->month = t->tm_mon + 1;
1826 tod->year = 1900+t->tm_year;
1827 tod->weekday = t->tm_wday;
1829 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1834 /***********************************************************************************
1835 Win9x NT tools get security descriptor.
1836 ***********************************************************************************/
1838 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf *sd_buf)
1840 SEC_DESC *psd = NULL;
1843 files_struct *fsp = NULL;
1847 connection_struct *conn = NULL;
1848 BOOL became_user = False;
1849 WERROR status = WERR_OK;
1855 /* Null password is ok - we are already an authenticated user... */
1856 null_pw = data_blob(NULL, 0);
1859 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1863 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1864 status = ntstatus_to_werror(nt_status);
1868 if (!become_user(conn, conn->vuid)) {
1869 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1870 status = WERR_ACCESS_DENIED;
1875 pstrcpy(tmp_file, file);
1876 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1878 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1879 status = WERR_ACCESS_DENIED;
1883 if (!check_name(file,conn)) {
1884 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1885 status = WERR_ACCESS_DENIED;
1889 nt_status = open_file_stat(conn, file, &st, &fsp);
1890 if (!NT_STATUS_IS_OK(nt_status)) {
1891 /* Perhaps it is a directory */
1892 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1893 nt_status = open_directory(conn, file, &st,
1894 READ_CONTROL_ACCESS,
1895 FILE_SHARE_READ|FILE_SHARE_WRITE,
1900 if (!NT_STATUS_IS_OK(nt_status)) {
1901 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1902 status = WERR_ACCESS_DENIED;
1907 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1910 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1911 status = WERR_ACCESS_DENIED;
1915 sd_buf->sd_size= sd_size;
1918 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1920 close_file(fsp, NORMAL_CLOSE);
1922 close_cnum(conn, p->pipe_user.vuid);
1928 close_file(fsp, NORMAL_CLOSE);
1935 close_cnum(conn, p->pipe_user.vuid);
1940 /***********************************************************************************
1941 Win9x NT tools set security descriptor.
1942 ***********************************************************************************/
1944 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf sd_buf)
1948 files_struct *fsp = NULL;
1952 connection_struct *conn = NULL;
1953 BOOL became_user = False;
1954 WERROR status = WERR_OK;
1959 /* Null password is ok - we are already an authenticated user... */
1960 null_pw = data_blob(NULL, 0);
1963 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1967 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1968 status = ntstatus_to_werror(nt_status);
1972 if (!become_user(conn, conn->vuid)) {
1973 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1974 status = WERR_ACCESS_DENIED;
1979 pstrcpy(tmp_file, file);
1980 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1982 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1983 status = WERR_ACCESS_DENIED;
1987 if (!check_name(file,conn)) {
1988 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1989 status = WERR_ACCESS_DENIED;
1994 nt_status = open_file_stat(conn, file, &st, &fsp);
1996 if (!NT_STATUS_IS_OK(nt_status)) {
1997 /* Perhaps it is a directory */
1998 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1999 nt_status = open_directory(conn, file, &st,
2000 FILE_READ_ATTRIBUTES,
2001 FILE_SHARE_READ|FILE_SHARE_WRITE,
2006 if (!NT_STATUS_IS_OK(nt_status)) {
2007 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
2008 status = WERR_ACCESS_DENIED;
2013 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
2016 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
2017 status = WERR_ACCESS_DENIED;
2021 close_file(fsp, NORMAL_CLOSE);
2023 close_cnum(conn, p->pipe_user.vuid);
2029 close_file(fsp, NORMAL_CLOSE);
2037 close_cnum(conn, p->pipe_user.vuid);
2043 /***********************************************************************************
2044 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2045 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2046 These disks would the disks listed by this function.
2047 Users could then create shares relative to these disks. Watch out for moving these disks around.
2048 "Nigel Williams" <nigel@veritas.com>.
2049 ***********************************************************************************/
2051 static const char *server_disks[] = {"C:"};
2053 static uint32 get_server_disk_count(void)
2055 return sizeof(server_disks)/sizeof(server_disks[0]);
2058 static uint32 init_server_disk_enum(uint32 *resume)
2060 uint32 server_disk_count = get_server_disk_count();
2062 /*resume can be an offset into the list for now*/
2064 if(*resume & 0x80000000)
2067 if(*resume > server_disk_count)
2068 *resume = server_disk_count;
2070 return server_disk_count - *resume;
2073 static const char *next_server_disk_enum(uint32 *resume)
2077 if(init_server_disk_enum(resume) == 0)
2080 disk = server_disks[*resume];
2084 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2089 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, const char *server_unc, uint32_t level, struct srvsvc_NetDiskInfo *info, uint32_t maxlen, uint32_t *totalentries, uint32_t *resume_handle)
2092 const char *disk_name;
2094 WERROR status = WERR_OK;
2096 *totalentries = init_server_disk_enum(resume_handle);
2099 if(!(info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2103 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2105 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2110 /*copy disk name into a unicode string*/
2112 info->disks[i].disk = disk_name;
2115 /* add a terminating null string. Is this there if there is more data to come? */
2120 info->disks[i].disk = "";
2125 /********************************************************************
2126 ********************************************************************/
2128 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2132 if ((flags != 0x0) && (flags != 0x80000000)) {
2133 return WERR_INVALID_PARAM;
2136 switch ( name_type ) {
2138 len = strlen_m(name);
2140 if ((flags == 0x0) && (len > 81)) {
2141 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2142 return WERR_INVALID_NAME;
2144 if ((flags == 0x80000000) && (len > 13)) {
2145 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2146 return WERR_INVALID_NAME;
2149 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2150 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2151 return WERR_INVALID_NAME;
2156 return WERR_UNKNOWN_LEVEL;
2163 /********************************************************************
2164 ********************************************************************/
2166 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2168 return WERR_ACCESS_DENIED;
2171 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetCharDevCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2173 p->rng_fault_state = True;
2174 return WERR_NOT_SUPPORTED;
2177 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2179 p->rng_fault_state = True;
2180 return WERR_NOT_SUPPORTED;
2183 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2185 p->rng_fault_state = True;
2186 return WERR_NOT_SUPPORTED;
2189 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, const char *server_unc, const char *user, uint32_t *level, union srvsvc_NetCharDevQCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2191 p->rng_fault_state = True;
2192 return WERR_NOT_SUPPORTED;
2195 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2197 p->rng_fault_state = True;
2198 return WERR_NOT_SUPPORTED;
2201 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, uint32_t level, union srvsvc_NetCharDevQInfo info, uint32_t *parm_error)
2203 p->rng_fault_state = True;
2204 return WERR_NOT_SUPPORTED;
2207 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2209 p->rng_fault_state = True;
2210 return WERR_NOT_SUPPORTED;
2213 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2215 p->rng_fault_state = True;
2216 return WERR_NOT_SUPPORTED;
2219 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2221 p->rng_fault_state = True;
2222 return WERR_NOT_SUPPORTED;
2225 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2227 p->rng_fault_state = True;
2228 return WERR_NOT_SUPPORTED;
2231 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2233 p->rng_fault_state = True;
2234 return WERR_NOT_SUPPORTED;
2237 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2239 p->rng_fault_state = True;
2240 return WERR_NOT_SUPPORTED;
2243 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetTransportCtr *transports, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2245 p->rng_fault_state = True;
2246 return WERR_NOT_SUPPORTED;
2249 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2251 p->rng_fault_state = True;
2252 return WERR_NOT_SUPPORTED;
2255 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2257 p->rng_fault_state = True;
2258 return WERR_NOT_SUPPORTED;
2261 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2263 p->rng_fault_state = True;
2264 return WERR_NOT_SUPPORTED;
2267 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, const char *server_unc, const char *path, uint8_t *can_path, uint32_t maxbuf, const char *prefix, uint32_t *pathtype, uint32_t pathflags)
2269 p->rng_fault_state = True;
2270 return WERR_NOT_SUPPORTED;
2273 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2275 p->rng_fault_state = True;
2276 return WERR_NOT_SUPPORTED;
2279 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2281 p->rng_fault_state = True;
2282 return WERR_NOT_SUPPORTED;
2285 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2287 p->rng_fault_state = True;
2288 return WERR_NOT_SUPPORTED;
2291 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2293 p->rng_fault_state = True;
2294 return WERR_NOT_SUPPORTED;
2297 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2299 p->rng_fault_state = True;
2300 return WERR_NOT_SUPPORTED;
2303 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2305 p->rng_fault_state = True;
2306 return WERR_NOT_SUPPORTED;
2309 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, const char *server_unc, const char *emulated_server_unc, const char *transport, uint32_t servicebitsofinterest, uint32_t servicebits, uint32_t updateimmediately)
2311 p->rng_fault_state = True;
2312 return WERR_NOT_SUPPORTED;
2315 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2317 p->rng_fault_state = True;
2318 return WERR_NOT_SUPPORTED;
2321 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2323 p->rng_fault_state = True;
2324 return WERR_NOT_SUPPORTED;
2327 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2329 p->rng_fault_state = True;
2330 return WERR_NOT_SUPPORTED;
2333 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2335 p->rng_fault_state = True;
2336 return WERR_NOT_SUPPORTED;
2339 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2341 p->rng_fault_state = True;
2342 return WERR_NOT_SUPPORTED;
2345 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2347 p->rng_fault_state = True;
2348 return WERR_NOT_SUPPORTED;
2351 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2353 p->rng_fault_state = True;
2354 return WERR_NOT_SUPPORTED;
2357 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2359 p->rng_fault_state = True;
2360 return WERR_NOT_SUPPORTED;
2363 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2365 p->rng_fault_state = True;
2366 return WERR_NOT_SUPPORTED;
2369 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2371 p->rng_fault_state = True;
2372 return WERR_NOT_SUPPORTED;
2375 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2377 p->rng_fault_state = True;
2378 return WERR_NOT_SUPPORTED;