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();
523 if (!(shares = share_list_all(ctx))) {
524 DEBUG(5, ("Could not list shares\n"));
525 return WERR_ACCESS_DENIED;
528 switch (info_level) {
530 if (!(ctr->ctr0 = talloc_zero(
531 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
536 if (!(ctr->ctr1 = talloc_zero(
537 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
542 if (!(ctr->ctr2 = talloc_zero(
543 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
548 if (!(ctr->ctr501 = talloc_zero(
549 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
554 if (!(ctr->ctr502 = talloc_zero(
555 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
560 if (!(ctr->ctr1004 = talloc_zero(
561 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
566 if (!(ctr->ctr1005 = talloc_zero(
567 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
572 if (!(ctr->ctr1006 = talloc_zero(
573 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
578 if (!(ctr->ctr1007 = talloc_zero(
579 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
584 if (!(ctr->ctr1501 = talloc_zero(
585 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
590 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
591 "value %d\n", info_level));
592 return WERR_UNKNOWN_LEVEL;
595 while ((share = next_share(shares)) != NULL) {
596 if (!lp_browseable(share->service)) {
599 if (!all_shares && is_hidden_share(share)) {
603 switch (info_level) {
606 struct srvsvc_NetShareInfo0 i;
607 init_srv_share_info_0(p, &i, share);
608 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
609 &ctr->ctr0->array, &ctr->ctr0->count);
610 if (ctr->ctr0->array == NULL) {
613 *total_entries = ctr->ctr0->count;
619 struct srvsvc_NetShareInfo1 i;
620 init_srv_share_info_1(p, &i, share);
621 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
622 &ctr->ctr1->array, &ctr->ctr1->count);
623 if (ctr->ctr1->array == NULL) {
626 *total_entries = ctr->ctr1->count;
632 struct srvsvc_NetShareInfo2 i;
633 init_srv_share_info_2(p, &i, share);
634 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
635 &ctr->ctr2->array, &ctr->ctr2->count);
636 if (ctr->ctr2->array == NULL) {
639 *total_entries = ctr->ctr2->count;
645 struct srvsvc_NetShareInfo501 i;
646 init_srv_share_info_501(p, &i, share);
647 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
648 &ctr->ctr501->array, &ctr->ctr501->count);
649 if (ctr->ctr501->array == NULL) {
652 *total_entries = ctr->ctr501->count;
658 struct srvsvc_NetShareInfo502 i;
659 init_srv_share_info_502(p, &i, share);
660 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
661 &ctr->ctr502->array, &ctr->ctr502->count);
662 if (ctr->ctr502->array == NULL) {
665 *total_entries = ctr->ctr502->count;
669 /* here for completeness but not currently used with enum
674 struct srvsvc_NetShareInfo1004 i;
675 init_srv_share_info_1004(p, &i, share);
676 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
677 &ctr->ctr1004->array, &ctr->ctr1004->count);
678 if (ctr->ctr1004->array == NULL) {
681 *total_entries = ctr->ctr1004->count;
687 struct srvsvc_NetShareInfo1005 i;
688 init_srv_share_info_1005(p, &i, share);
689 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
690 &ctr->ctr1005->array, &ctr->ctr1005->count);
691 if (ctr->ctr1005->array == NULL) {
694 *total_entries = ctr->ctr1005->count;
700 struct srvsvc_NetShareInfo1006 i;
701 init_srv_share_info_1006(p, &i, share);
702 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
703 &ctr->ctr1006->array, &ctr->ctr1006->count);
704 if (ctr->ctr1006->array == NULL) {
707 *total_entries = ctr->ctr1006->count;
713 struct srvsvc_NetShareInfo1007 i;
714 init_srv_share_info_1007(p, &i, share);
715 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
716 &ctr->ctr1007->array, &ctr->ctr1007->count);
717 if (ctr->ctr1007->array == NULL) {
720 *total_entries = ctr->ctr1007->count;
726 struct sec_desc_buf i;
727 init_srv_share_info_1501(p, &i, share);
728 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
729 &ctr->ctr1501->array, &ctr->ctr1501->count);
730 if (ctr->ctr1501->array == NULL) {
733 *total_entries = ctr->ctr1501->count;
747 /*******************************************************************
748 fill in a sess info level 0 structure.
749 ********************************************************************/
751 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
753 struct sessionid *session_list;
754 uint32 num_entries = 0;
755 (*stot) = list_sessions(&session_list);
761 SAFE_FREE(session_list);
765 DEBUG(5,("init_srv_sess_0_ss0\n"));
767 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
770 for (; (*snum) < (*stot); (*snum)++) {
771 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
775 ss0->count = num_entries;
777 if ((*snum) >= (*stot)) {
785 SAFE_FREE(session_list);
788 /*******************************************************************
789 ********************************************************************/
791 static void sess_file_fn( const struct share_mode_entry *e,
792 const char *sharepath, const char *fname,
795 struct sess_file_count *sess = (struct sess_file_count *)private_data;
797 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
804 /*******************************************************************
805 ********************************************************************/
807 static int net_count_files( uid_t uid, pid_t pid )
809 struct sess_file_count s_file_cnt;
811 s_file_cnt.count = 0;
812 s_file_cnt.uid = uid;
813 s_file_cnt.pid = pid;
815 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
817 return s_file_cnt.count;
820 /*******************************************************************
821 fill in a sess info level 1 structure.
822 ********************************************************************/
824 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
826 struct sessionid *session_list;
827 uint32 num_entries = 0;
828 time_t now = time(NULL);
845 (*stot) = list_sessions(&session_list);
847 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
849 for (; (*snum) < (*stot); (*snum)++) {
852 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
856 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
857 session_list[*snum].username));
861 connect_time = (uint32)(now - session_list[*snum].connect_start);
862 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
863 guest = strequal( session_list[*snum].username, lp_guestaccount() );
865 ss1->array[num_entries].client = session_list[*snum].remote_machine;
866 ss1->array[num_entries].user = session_list[*snum].username;
867 ss1->array[num_entries].num_open = num_files;
868 ss1->array[num_entries].time = connect_time;
869 ss1->array[num_entries].idle_time = 0;
870 ss1->array[num_entries].user_flags = guest;
875 ss1->count = num_entries;
877 if ((*snum) >= (*stot)) {
881 SAFE_FREE(session_list);
884 /*******************************************************************
885 makes a SRV_R_NET_SESS_ENUM structure.
886 ********************************************************************/
888 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
889 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
891 WERROR status = WERR_OK;
892 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
894 switch (switch_value) {
896 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
897 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
900 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
901 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
904 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
905 if (resume_hnd != NULL)
907 (*total_entries) = 0;
909 status = WERR_UNKNOWN_LEVEL;
916 /*******************************************************************
917 fill in a conn info level 0 structure.
918 ********************************************************************/
920 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
922 uint32 num_entries = 0;
931 DEBUG(5,("init_srv_conn_0_ss0\n"));
934 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
935 for (; (*snum) < (*stot); (*snum)++) {
937 ss0->array[num_entries].conn_id = (*stot);
939 /* move on to creating next connection */
940 /* move on to creating next conn */
944 ss0->count = num_entries;
946 if ((*snum) >= (*stot)) {
958 /*******************************************************************
959 fill in a conn info level 1 structure.
960 ********************************************************************/
962 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
964 uint32 num_entries = 0;
973 DEBUG(5,("init_srv_conn_1_ss1\n"));
976 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
977 for (; (*snum) < (*stot); (*snum)++) {
978 ss1->array[num_entries].conn_id = (*stot);
979 ss1->array[num_entries].conn_type = 0x3;
980 ss1->array[num_entries].num_open = 1;
981 ss1->array[num_entries].num_users = 1;
982 ss1->array[num_entries].conn_time = 3;
983 ss1->array[num_entries].user = "dummy_user";
984 ss1->array[num_entries].share = "IPC$";
986 /* move on to creating next connection */
987 /* move on to creating next conn */
991 ss1->count = num_entries;
993 if ((*snum) >= (*stot)) {
1005 /*******************************************************************
1006 makes a SRV_R_NET_CONN_ENUM structure.
1007 ********************************************************************/
1009 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1010 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1012 WERROR status = WERR_OK;
1013 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1015 switch (switch_value) {
1017 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1020 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1023 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1026 (*total_entries) = 0;
1027 status = WERR_UNKNOWN_LEVEL;
1034 /*******************************************************************
1035 makes a SRV_R_NET_FILE_ENUM structure.
1036 ********************************************************************/
1038 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1040 TALLOC_CTX *ctx = get_talloc_ctx();
1043 /* TODO -- Windows enumerates
1045 (c) open directories and files */
1047 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1049 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1050 if ( !W_ERROR_IS_OK(status))
1053 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1054 if ( !W_ERROR_IS_OK(status))
1057 ctr->ctr3->count = *num_entries;
1062 /*******************************************************************
1063 *******************************************************************/
1065 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)
1069 return net_file_enum_3(p, ctr, resume_handle, totalentries );
1071 return WERR_UNKNOWN_LEVEL;
1077 /*******************************************************************
1079 ********************************************************************/
1081 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1083 WERROR status = WERR_OK;
1087 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1089 if (!pipe_access_check(p)) {
1090 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1091 return WERR_ACCESS_DENIED;
1096 /* Technically level 102 should only be available to
1097 Administrators but there isn't anything super-secret
1098 here, as most of it is made up. */
1101 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1103 info->info102->platform_id = 500;
1104 info->info102->version_major = lp_major_announce_version();
1105 info->info102->version_minor = lp_minor_announce_version();
1106 info->info102->server_name = global_myname();
1107 info->info102->server_type = lp_default_server_announce();
1108 info->info102->userpath = "C:\\";
1109 info->info102->licenses = 10000;
1110 info->info102->anndelta = 3000;
1111 info->info102->disc = 0xf;
1112 info->info102->users = 0xffffffff;
1113 info->info102->hidden = 0;
1114 info->info102->announce = 240;
1115 info->info102->comment = lp_serverstring();
1118 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1119 info->info101->platform_id = 500;
1120 info->info101->server_name = global_myname();
1121 info->info101->version_major = lp_major_announce_version();
1122 info->info101->version_minor = lp_minor_announce_version();
1123 info->info101->server_type = lp_default_server_announce();
1124 info->info101->comment = lp_serverstring();
1127 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1128 info->info100->platform_id = 500;
1129 info->info100->server_name = global_myname();
1132 return WERR_UNKNOWN_LEVEL;
1136 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1141 /*******************************************************************
1143 ********************************************************************/
1145 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1147 /* Set up the net server set info structure. */
1152 /*******************************************************************
1154 ********************************************************************/
1156 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)
1158 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1163 return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1166 /*******************************************************************
1168 ********************************************************************/
1170 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)
1172 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1177 return init_srv_sess_info_ctr(p, ctr,
1183 /*******************************************************************
1185 ********************************************************************/
1187 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1189 struct sessionid *session_list;
1190 int num_sessions, snum;
1193 char *machine = talloc_strdup(p->mem_ctx, server_unc);
1195 /* strip leading backslashes if any */
1196 while (machine[0] == '\\') {
1197 memmove(machine, &machine[1], strlen(machine));
1200 num_sessions = list_sessions(&session_list);
1202 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1204 status = WERR_ACCESS_DENIED;
1206 /* fail out now if you are not root or not a domain admin */
1208 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1209 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1214 for (snum = 0; snum < num_sessions; snum++) {
1216 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1217 strequal(session_list[snum].remote_machine, machine)) {
1219 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1224 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1228 SAFE_FREE(session_list);
1233 /*******************************************************************
1235 ********************************************************************/
1237 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)
1239 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1241 if (!pipe_access_check(p)) {
1242 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1243 return WERR_ACCESS_DENIED;
1246 /* Create the list of shares for the response. */
1247 return init_srv_share_info_ctr(p, ctr, *level,
1248 resume_handle, totalentries, True);
1251 /*******************************************************************
1253 ********************************************************************/
1255 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)
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\n"));
1261 return WERR_ACCESS_DENIED;
1264 /* Create the list of shares for the response. */
1265 return init_srv_share_info_ctr(p, ctr, *level,
1266 resume_handle, totalentries, False);
1269 /*******************************************************************
1271 ********************************************************************/
1273 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1275 const struct share_params *params;
1277 params = get_share_params(p->mem_ctx, share_name);
1279 if (params != NULL) {
1282 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1283 init_srv_share_info_0(p, info->info0,
1287 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1288 init_srv_share_info_1(p, info->info1,
1292 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1293 init_srv_share_info_2(p, info->info2,
1297 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1298 init_srv_share_info_501(p, info->info501,
1302 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1303 init_srv_share_info_502(p, info->info502,
1307 /* here for completeness */
1309 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1310 init_srv_share_info_1004(p, info->info1004,
1314 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1315 init_srv_share_info_1005(p, info->info1005,
1319 /* here for completeness 1006 - 1501 */
1321 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1322 init_srv_share_info_1006(p, info->info1006,
1326 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1327 init_srv_share_info_1007(p, info->info1007,
1331 info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1332 init_srv_share_info_1501(p, info->info1501,
1336 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1337 "switch value %d\n", level));
1338 return WERR_UNKNOWN_LEVEL;
1342 return WERR_INVALID_NAME;
1348 /*******************************************************************
1349 Check a given DOS pathname is valid for a share.
1350 ********************************************************************/
1352 char *valid_share_pathname(char *dos_pathname)
1356 /* Convert any '\' paths to '/' */
1357 unix_format(dos_pathname);
1358 unix_clean_name(dos_pathname);
1360 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1362 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1365 /* Only absolute paths allowed. */
1372 /*******************************************************************
1373 Net share set info. Modify share details.
1374 ********************************************************************/
1376 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)
1385 SEC_DESC *psd = NULL;
1386 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1387 BOOL is_disk_op = False;
1388 int max_connections = 0;
1389 fstring tmp_share_name;
1391 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1395 if ( strequal(share_name,"IPC$")
1396 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1397 || strequal(share_name,"global") )
1399 return WERR_ACCESS_DENIED;
1402 fstrcpy(tmp_share_name, share_name);
1403 snum = find_service(tmp_share_name);
1405 /* Does this share exist ? */
1407 return WERR_NET_NAME_NOT_FOUND;
1409 /* No change to printer shares. */
1410 if (lp_print_ok(snum))
1411 return WERR_ACCESS_DENIED;
1413 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1415 /* fail out now if you are not root and not a disk op */
1417 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1418 return WERR_ACCESS_DENIED;
1422 pstrcpy(pathname, lp_pathname(snum));
1423 pstrcpy(comment, info.info1->comment);
1424 type = info.info1->type;
1428 pstrcpy(comment, info.info2->comment);
1429 pstrcpy(pathname, info.info2->path);
1430 type = info.info2->type;
1431 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1435 /* not supported on set but here for completeness */
1437 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1438 type = q_u->info.share.info501.info_501.type;
1443 pstrcpy(comment, info.info502->comment);
1444 pstrcpy(pathname, info.info502->path);
1445 type = info.info502->type;
1446 psd = info.info502->sd;
1447 map_generic_share_sd_bits(psd);
1450 pstrcpy(pathname, lp_pathname(snum));
1451 pstrcpy(comment, info.info1004->comment);
1452 type = STYPE_DISKTREE;
1455 /* XP re-sets the csc policy even if it wasn't changed by the
1456 user, so we must compare it to see if it's what is set in
1457 smb.conf, so that we can contine other ops like setting
1459 if (((info.info1005->dfs_flags &
1460 SHARE_1005_CSC_POLICY_MASK) >>
1461 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1464 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1465 return WERR_ACCESS_DENIED;
1469 return WERR_ACCESS_DENIED;
1471 pstrcpy(pathname, lp_pathname(snum));
1472 pstrcpy(comment, lp_comment(snum));
1473 psd = info.info1501->sd;
1474 map_generic_share_sd_bits(psd);
1475 type = STYPE_DISKTREE;
1478 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1479 return WERR_UNKNOWN_LEVEL;
1482 /* We can only modify disk shares. */
1483 if (type != STYPE_DISKTREE)
1484 return WERR_ACCESS_DENIED;
1486 /* Check if the pathname is valid. */
1487 if (!(path = valid_share_pathname( pathname )))
1488 return WERR_OBJECT_PATH_INVALID;
1490 /* Ensure share name, pathname and comment don't contain '"' characters. */
1491 string_replace(tmp_share_name, '"', ' ');
1492 string_replace(path, '"', ' ');
1493 string_replace(comment, '"', ' ');
1495 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1496 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1498 /* Only call modify function if something changed. */
1500 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1501 || (lp_max_connections(snum) != max_connections) )
1503 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1504 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1505 return WERR_ACCESS_DENIED;
1508 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1509 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1511 DEBUG(10,("_srv_net_share_set_info: 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(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1526 /********* END SeDiskOperatorPrivilege BLOCK *********/
1528 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1531 return WERR_ACCESS_DENIED;
1533 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1536 /* Replace SD if changed. */
1541 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1544 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1545 if (!set_share_security(p->mem_ctx, share_name, psd))
1546 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1551 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1556 /*******************************************************************
1557 Net share add. Call 'add_share_command "sharename" "pathname"
1558 "comment" "max connections = "
1559 ********************************************************************/
1561 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1571 SEC_DESC *psd = NULL;
1572 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1574 int max_connections = 0;
1576 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1580 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1582 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1583 return WERR_ACCESS_DENIED;
1585 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1586 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1587 return WERR_ACCESS_DENIED;
1592 /* No path. Not enough info in a level 0 to do anything. */
1593 return WERR_ACCESS_DENIED;
1595 /* Not enough info in a level 1 to do anything. */
1596 return WERR_ACCESS_DENIED;
1598 pstrcpy(share_name, info.info2->name);
1599 pstrcpy(comment, info.info2->comment);
1600 pstrcpy(pathname, info.info2->path);
1601 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1602 type = info.info2->type;
1605 /* No path. Not enough info in a level 501 to do anything. */
1606 return WERR_ACCESS_DENIED;
1608 pstrcpy(share_name, info.info502->name);
1609 pstrcpy(comment, info.info502->comment);
1610 pstrcpy(pathname, info.info502->path);
1611 type = info.info502->type;
1612 psd = info.info502->sd;
1613 map_generic_share_sd_bits(psd);
1616 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1622 return WERR_ACCESS_DENIED;
1624 /* DFS only level. */
1625 return WERR_ACCESS_DENIED;
1627 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1628 return WERR_UNKNOWN_LEVEL;
1631 /* check for invalid share names */
1633 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1634 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1635 return WERR_INVALID_NAME;
1638 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1639 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1641 return WERR_ACCESS_DENIED;
1644 snum = find_service(share_name);
1646 /* Share already exists. */
1648 return WERR_ALREADY_EXISTS;
1650 /* We can only add disk shares. */
1651 if (type != STYPE_DISKTREE)
1652 return WERR_ACCESS_DENIED;
1654 /* Check if the pathname is valid. */
1655 if (!(path = valid_share_pathname( pathname )))
1656 return WERR_OBJECT_PATH_INVALID;
1658 /* Ensure share name, pathname and comment don't contain '"' characters. */
1659 string_replace(share_name, '"', ' ');
1660 string_replace(path, '"', ' ');
1661 string_replace(comment, '"', ' ');
1663 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1671 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1673 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1678 if ( (ret = smbrun(command, NULL)) == 0 ) {
1679 /* Tell everyone we updated smb.conf. */
1680 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1686 /********* END SeDiskOperatorPrivilege BLOCK *********/
1688 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1691 return WERR_ACCESS_DENIED;
1694 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1695 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1700 * We don't call reload_services() here, the message will
1701 * cause this to be done before the next packet is read
1702 * from the client. JRA.
1705 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1710 /*******************************************************************
1711 Net share delete. Call "delete share command" with the share name as
1713 ********************************************************************/
1715 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1719 struct share_params *params;
1720 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1723 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1725 if ( strequal(share_name,"IPC$")
1726 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1727 || strequal(share_name,"global") )
1729 return WERR_ACCESS_DENIED;
1732 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1733 return WERR_NO_SUCH_SHARE;
1736 /* No change to printer shares. */
1737 if (lp_print_ok(params->service))
1738 return WERR_ACCESS_DENIED;
1740 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1742 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1743 return WERR_ACCESS_DENIED;
1745 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1746 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1747 return WERR_ACCESS_DENIED;
1750 if (asprintf(&command, "%s \"%s\" \"%s\"",
1751 lp_delete_share_cmd(), dyn_CONFIGFILE,
1752 lp_servicename(params->service)) == -1) {
1756 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1758 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1763 if ( (ret = smbrun(command, NULL)) == 0 ) {
1764 /* Tell everyone we updated smb.conf. */
1765 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1773 /********* END SeDiskOperatorPrivilege BLOCK *********/
1775 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1778 return WERR_ACCESS_DENIED;
1780 /* Delete the SD in the database. */
1781 delete_share_security(params);
1783 lp_killservice(params->service);
1788 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1790 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1792 return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1795 /*******************************************************************
1797 ********************************************************************/
1799 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1802 time_t unixdate = time(NULL);
1803 WERROR status = WERR_OK;
1805 /* We do this call first as if we do it *after* the gmtime call
1806 it overwrites the pointed-to values. JRA */
1808 uint32 zone = get_time_zone(unixdate)/60;
1810 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1812 t = gmtime(&unixdate);
1815 tod->elapsed = unixdate;
1817 tod->hours = t->tm_hour;
1818 tod->mins = t->tm_min;
1819 tod->secs = t->tm_sec;
1821 tod->timezone = zone;
1822 tod->tinterval = 10000;
1823 tod->day = t->tm_mday;
1824 tod->month = t->tm_mon + 1;
1825 tod->year = 1900+t->tm_year;
1826 tod->weekday = t->tm_wday;
1828 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1833 /***********************************************************************************
1834 Win9x NT tools get security descriptor.
1835 ***********************************************************************************/
1837 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)
1839 SEC_DESC *psd = NULL;
1842 files_struct *fsp = NULL;
1846 connection_struct *conn = NULL;
1847 BOOL became_user = False;
1848 WERROR status = WERR_OK;
1854 /* Null password is ok - we are already an authenticated user... */
1855 null_pw = data_blob(NULL, 0);
1858 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1862 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1863 status = ntstatus_to_werror(nt_status);
1867 if (!become_user(conn, conn->vuid)) {
1868 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1869 status = WERR_ACCESS_DENIED;
1874 pstrcpy(tmp_file, file);
1875 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1877 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1878 status = WERR_ACCESS_DENIED;
1882 if (!check_name(file,conn)) {
1883 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1884 status = WERR_ACCESS_DENIED;
1888 nt_status = open_file_stat(conn, file, &st, &fsp);
1889 if (!NT_STATUS_IS_OK(nt_status)) {
1890 /* Perhaps it is a directory */
1891 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1892 nt_status = open_directory(conn, file, &st,
1893 READ_CONTROL_ACCESS,
1894 FILE_SHARE_READ|FILE_SHARE_WRITE,
1899 if (!NT_STATUS_IS_OK(nt_status)) {
1900 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1901 status = WERR_ACCESS_DENIED;
1906 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1909 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1910 status = WERR_ACCESS_DENIED;
1914 sd_buf->sd_size= sd_size;
1917 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1919 close_file(fsp, NORMAL_CLOSE);
1921 close_cnum(conn, p->pipe_user.vuid);
1927 close_file(fsp, NORMAL_CLOSE);
1934 close_cnum(conn, p->pipe_user.vuid);
1939 /***********************************************************************************
1940 Win9x NT tools set security descriptor.
1941 ***********************************************************************************/
1943 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)
1947 files_struct *fsp = NULL;
1951 connection_struct *conn = NULL;
1952 BOOL became_user = False;
1953 WERROR status = WERR_OK;
1958 /* Null password is ok - we are already an authenticated user... */
1959 null_pw = data_blob(NULL, 0);
1962 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1966 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1967 status = ntstatus_to_werror(nt_status);
1971 if (!become_user(conn, conn->vuid)) {
1972 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1973 status = WERR_ACCESS_DENIED;
1978 pstrcpy(tmp_file, file);
1979 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1981 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1982 status = WERR_ACCESS_DENIED;
1986 if (!check_name(file,conn)) {
1987 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1988 status = WERR_ACCESS_DENIED;
1993 nt_status = open_file_stat(conn, file, &st, &fsp);
1995 if (!NT_STATUS_IS_OK(nt_status)) {
1996 /* Perhaps it is a directory */
1997 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1998 nt_status = open_directory(conn, file, &st,
1999 FILE_READ_ATTRIBUTES,
2000 FILE_SHARE_READ|FILE_SHARE_WRITE,
2005 if (!NT_STATUS_IS_OK(nt_status)) {
2006 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
2007 status = WERR_ACCESS_DENIED;
2012 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
2015 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
2016 status = WERR_ACCESS_DENIED;
2020 close_file(fsp, NORMAL_CLOSE);
2022 close_cnum(conn, p->pipe_user.vuid);
2028 close_file(fsp, NORMAL_CLOSE);
2036 close_cnum(conn, p->pipe_user.vuid);
2042 /***********************************************************************************
2043 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2044 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2045 These disks would the disks listed by this function.
2046 Users could then create shares relative to these disks. Watch out for moving these disks around.
2047 "Nigel Williams" <nigel@veritas.com>.
2048 ***********************************************************************************/
2050 static const char *server_disks[] = {"C:"};
2052 static uint32 get_server_disk_count(void)
2054 return sizeof(server_disks)/sizeof(server_disks[0]);
2057 static uint32 init_server_disk_enum(uint32 *resume)
2059 uint32 server_disk_count = get_server_disk_count();
2061 /*resume can be an offset into the list for now*/
2063 if(*resume & 0x80000000)
2066 if(*resume > server_disk_count)
2067 *resume = server_disk_count;
2069 return server_disk_count - *resume;
2072 static const char *next_server_disk_enum(uint32 *resume)
2076 if(init_server_disk_enum(resume) == 0)
2079 disk = server_disks[*resume];
2083 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2088 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)
2091 const char *disk_name;
2093 WERROR status = WERR_OK;
2095 *totalentries = init_server_disk_enum(resume_handle);
2098 if(!(info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2102 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2104 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2109 /*copy disk name into a unicode string*/
2111 info->disks[i].disk = disk_name;
2114 /* add a terminating null string. Is this there if there is more data to come? */
2119 info->disks[i].disk = "";
2124 /********************************************************************
2125 ********************************************************************/
2127 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2131 if ((flags != 0x0) && (flags != 0x80000000)) {
2132 return WERR_INVALID_PARAM;
2135 switch ( name_type ) {
2137 len = strlen_m(name);
2139 if ((flags == 0x0) && (len > 81)) {
2140 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2141 return WERR_INVALID_NAME;
2143 if ((flags == 0x80000000) && (len > 13)) {
2144 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2145 return WERR_INVALID_NAME;
2148 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2149 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2150 return WERR_INVALID_NAME;
2155 return WERR_UNKNOWN_LEVEL;
2162 /********************************************************************
2163 ********************************************************************/
2165 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2167 return WERR_ACCESS_DENIED;
2170 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)
2172 p->rng_fault_state = True;
2173 return WERR_NOT_SUPPORTED;
2176 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2178 p->rng_fault_state = True;
2179 return WERR_NOT_SUPPORTED;
2182 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2184 p->rng_fault_state = True;
2185 return WERR_NOT_SUPPORTED;
2188 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)
2190 p->rng_fault_state = True;
2191 return WERR_NOT_SUPPORTED;
2194 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2196 p->rng_fault_state = True;
2197 return WERR_NOT_SUPPORTED;
2200 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)
2202 p->rng_fault_state = True;
2203 return WERR_NOT_SUPPORTED;
2206 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2208 p->rng_fault_state = True;
2209 return WERR_NOT_SUPPORTED;
2212 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2214 p->rng_fault_state = True;
2215 return WERR_NOT_SUPPORTED;
2218 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2220 p->rng_fault_state = True;
2221 return WERR_NOT_SUPPORTED;
2224 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2226 p->rng_fault_state = True;
2227 return WERR_NOT_SUPPORTED;
2230 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2232 p->rng_fault_state = True;
2233 return WERR_NOT_SUPPORTED;
2236 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2238 p->rng_fault_state = True;
2239 return WERR_NOT_SUPPORTED;
2242 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)
2244 p->rng_fault_state = True;
2245 return WERR_NOT_SUPPORTED;
2248 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2250 p->rng_fault_state = True;
2251 return WERR_NOT_SUPPORTED;
2254 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2256 p->rng_fault_state = True;
2257 return WERR_NOT_SUPPORTED;
2260 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2262 p->rng_fault_state = True;
2263 return WERR_NOT_SUPPORTED;
2266 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)
2268 p->rng_fault_state = True;
2269 return WERR_NOT_SUPPORTED;
2272 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2274 p->rng_fault_state = True;
2275 return WERR_NOT_SUPPORTED;
2278 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2280 p->rng_fault_state = True;
2281 return WERR_NOT_SUPPORTED;
2284 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2286 p->rng_fault_state = True;
2287 return WERR_NOT_SUPPORTED;
2290 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2292 p->rng_fault_state = True;
2293 return WERR_NOT_SUPPORTED;
2296 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2298 p->rng_fault_state = True;
2299 return WERR_NOT_SUPPORTED;
2302 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2304 p->rng_fault_state = True;
2305 return WERR_NOT_SUPPORTED;
2308 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)
2310 p->rng_fault_state = True;
2311 return WERR_NOT_SUPPORTED;
2314 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2316 p->rng_fault_state = True;
2317 return WERR_NOT_SUPPORTED;
2320 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2322 p->rng_fault_state = True;
2323 return WERR_NOT_SUPPORTED;
2326 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2328 p->rng_fault_state = True;
2329 return WERR_NOT_SUPPORTED;
2332 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2334 p->rng_fault_state = True;
2335 return WERR_NOT_SUPPORTED;
2338 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2340 p->rng_fault_state = True;
2341 return WERR_NOT_SUPPORTED;
2344 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2346 p->rng_fault_state = True;
2347 return WERR_NOT_SUPPORTED;
2350 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2352 p->rng_fault_state = True;
2353 return WERR_NOT_SUPPORTED;
2356 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2358 p->rng_fault_state = True;
2359 return WERR_NOT_SUPPORTED;
2362 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2364 p->rng_fault_state = True;
2365 return WERR_NOT_SUPPORTED;
2368 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2370 p->rng_fault_state = True;
2371 return WERR_NOT_SUPPORTED;
2374 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2376 p->rng_fault_state = True;
2377 return WERR_NOT_SUPPORTED;