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;
507 DEBUG(5,("init_srv_share_info_ctr\n"));
513 /* Ensure all the usershares are loaded. */
515 load_usershare_shares();
520 if (!(shares = share_list_all(ctx))) {
521 DEBUG(5, ("Could not list shares\n"));
522 return WERR_ACCESS_DENIED;
525 switch (info_level) {
527 ctr->ctr0 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr0);
530 ctr->ctr1 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1);
533 ctr->ctr2 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr2);
536 ctr->ctr501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr501);
539 ctr->ctr502 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr502);
542 ctr->ctr1004 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1004);
545 ctr->ctr1005 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1005);
548 ctr->ctr1006 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1006);
551 ctr->ctr1007 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1007);
554 ctr->ctr1501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1501);
557 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
558 "value %d\n", info_level));
559 return WERR_UNKNOWN_LEVEL;
562 while ((share = next_share(shares)) != NULL) {
563 if (!lp_browseable(share->service)) {
566 if (!all_shares && is_hidden_share(share)) {
570 switch (info_level) {
573 struct srvsvc_NetShareInfo0 i;
574 init_srv_share_info_0(p, &i, share);
575 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
576 &ctr->ctr0->array, &ctr->ctr0->count);
577 if (ctr->ctr0->array == NULL) {
580 *total_entries = ctr->ctr0->count;
586 struct srvsvc_NetShareInfo1 i;
587 init_srv_share_info_1(p, &i, share);
588 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
589 &ctr->ctr1->array, &ctr->ctr1->count);
590 if (ctr->ctr1->array == NULL) {
593 *total_entries = ctr->ctr1->count;
599 struct srvsvc_NetShareInfo2 i;
600 init_srv_share_info_2(p, &i, share);
601 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
602 &ctr->ctr2->array, &ctr->ctr2->count);
603 if (ctr->ctr2->array == NULL) {
606 *total_entries = ctr->ctr2->count;
612 struct srvsvc_NetShareInfo501 i;
613 init_srv_share_info_501(p, &i, share);
614 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
615 &ctr->ctr501->array, &ctr->ctr501->count);
616 if (ctr->ctr501->array == NULL) {
619 *total_entries = ctr->ctr501->count;
625 struct srvsvc_NetShareInfo502 i;
626 init_srv_share_info_502(p, &i, share);
627 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
628 &ctr->ctr502->array, &ctr->ctr502->count);
629 if (ctr->ctr502->array == NULL) {
632 *total_entries = ctr->ctr502->count;
636 /* here for completeness but not currently used with enum
641 struct srvsvc_NetShareInfo1004 i;
642 init_srv_share_info_1004(p, &i, share);
643 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
644 &ctr->ctr1004->array, &ctr->ctr1004->count);
645 if (ctr->ctr1004->array == NULL) {
648 *total_entries = ctr->ctr1004->count;
654 struct srvsvc_NetShareInfo1005 i;
655 init_srv_share_info_1005(p, &i, share);
656 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
657 &ctr->ctr1005->array, &ctr->ctr1005->count);
658 if (ctr->ctr1005->array == NULL) {
661 *total_entries = ctr->ctr1005->count;
667 struct srvsvc_NetShareInfo1006 i;
668 init_srv_share_info_1006(p, &i, share);
669 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
670 &ctr->ctr1006->array, &ctr->ctr1006->count);
671 if (ctr->ctr1006->array == NULL) {
674 *total_entries = ctr->ctr1006->count;
680 struct srvsvc_NetShareInfo1007 i;
681 init_srv_share_info_1007(p, &i, share);
682 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
683 &ctr->ctr1007->array, &ctr->ctr1007->count);
684 if (ctr->ctr1007->array == NULL) {
687 *total_entries = ctr->ctr1007->count;
693 struct sec_desc_buf i;
694 init_srv_share_info_1501(p, &i, share);
695 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
696 &ctr->ctr1501->array, &ctr->ctr1501->count);
697 if (ctr->ctr1501->array == NULL) {
700 *total_entries = ctr->ctr1501->count;
711 /*******************************************************************
712 fill in a sess info level 0 structure.
713 ********************************************************************/
715 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
717 struct sessionid *session_list;
718 uint32 num_entries = 0;
719 (*stot) = list_sessions(&session_list);
725 SAFE_FREE(session_list);
729 DEBUG(5,("init_srv_sess_0_ss0\n"));
731 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
734 for (; (*snum) < (*stot); (*snum)++) {
735 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
739 ss0->count = num_entries;
741 if ((*snum) >= (*stot)) {
749 SAFE_FREE(session_list);
752 /*******************************************************************
753 ********************************************************************/
755 static void sess_file_fn( const struct share_mode_entry *e,
756 const char *sharepath, const char *fname,
759 struct sess_file_count *sess = (struct sess_file_count *)private_data;
761 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
768 /*******************************************************************
769 ********************************************************************/
771 static int net_count_files( uid_t uid, pid_t pid )
773 struct sess_file_count s_file_cnt;
775 s_file_cnt.count = 0;
776 s_file_cnt.uid = uid;
777 s_file_cnt.pid = pid;
779 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
781 return s_file_cnt.count;
784 /*******************************************************************
785 fill in a sess info level 1 structure.
786 ********************************************************************/
788 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
790 struct sessionid *session_list;
791 uint32 num_entries = 0;
792 time_t now = time(NULL);
808 (*stot) = list_sessions(&session_list);
810 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
812 for (; (*snum) < (*stot); (*snum)++) {
815 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
819 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
820 session_list[*snum].username));
824 connect_time = (uint32)(now - session_list[*snum].connect_start);
825 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
826 guest = strequal( session_list[*snum].username, lp_guestaccount() );
828 ss1->array[num_entries].client = session_list[*snum].remote_machine;
829 ss1->array[num_entries].user = session_list[*snum].username;
830 ss1->array[num_entries].num_open = num_files;
831 ss1->array[num_entries].time = connect_time;
832 ss1->array[num_entries].idle_time = 0;
833 ss1->array[num_entries].user_flags = guest;
838 ss1->count = num_entries;
840 if ((*snum) >= (*stot)) {
844 SAFE_FREE(session_list);
847 /*******************************************************************
848 makes a SRV_R_NET_SESS_ENUM structure.
849 ********************************************************************/
851 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
852 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
854 WERROR status = WERR_OK;
855 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
857 switch (switch_value) {
859 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
860 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
863 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
864 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
867 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
869 (*total_entries) = 0;
871 status = WERR_UNKNOWN_LEVEL;
878 /*******************************************************************
879 fill in a conn info level 0 structure.
880 ********************************************************************/
882 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
884 uint32 num_entries = 0;
892 DEBUG(5,("init_srv_conn_0_ss0\n"));
895 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
896 for (; (*snum) < (*stot); (*snum)++) {
898 ss0->array[num_entries].conn_id = (*stot);
900 /* move on to creating next connection */
901 /* move on to creating next conn */
905 ss0->count = num_entries;
907 if ((*snum) >= (*stot)) {
919 /*******************************************************************
920 fill in a conn info level 1 structure.
921 ********************************************************************/
923 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
925 uint32 num_entries = 0;
933 DEBUG(5,("init_srv_conn_1_ss1\n"));
936 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
937 for (; (*snum) < (*stot); (*snum)++) {
938 ss1->array[num_entries].conn_id = (*stot);
939 ss1->array[num_entries].conn_type = 0x3;
940 ss1->array[num_entries].num_open = 1;
941 ss1->array[num_entries].num_users = 1;
942 ss1->array[num_entries].conn_time = 3;
943 ss1->array[num_entries].user = "dummy_user";
944 ss1->array[num_entries].share = "IPC$";
946 /* move on to creating next connection */
947 /* move on to creating next conn */
951 ss1->count = num_entries;
953 if ((*snum) >= (*stot)) {
965 /*******************************************************************
966 makes a SRV_R_NET_CONN_ENUM structure.
967 ********************************************************************/
969 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
970 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
972 WERROR status = WERR_OK;
973 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
975 switch (switch_value) {
977 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
980 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
983 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
986 (*total_entries) = 0;
987 status = WERR_UNKNOWN_LEVEL;
994 /*******************************************************************
995 makes a SRV_R_NET_FILE_ENUM structure.
996 ********************************************************************/
998 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1000 TALLOC_CTX *ctx = get_talloc_ctx();
1003 /* TODO -- Windows enumerates
1005 (c) open directories and files */
1007 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1009 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1010 if ( !W_ERROR_IS_OK(status))
1013 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1014 if ( !W_ERROR_IS_OK(status))
1017 ctr->ctr3->count = *num_entries;
1022 /*******************************************************************
1023 *******************************************************************/
1025 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)
1029 return net_file_enum_3(p, ctr, resume_handle, totalentries );
1031 return WERR_UNKNOWN_LEVEL;
1037 /*******************************************************************
1039 ********************************************************************/
1041 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1043 WERROR status = WERR_OK;
1047 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1049 if (!pipe_access_check(p)) {
1050 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1051 return WERR_ACCESS_DENIED;
1056 /* Technically level 102 should only be available to
1057 Administrators but there isn't anything super-secret
1058 here, as most of it is made up. */
1061 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1063 info->info102->platform_id = 500;
1064 info->info102->version_major = lp_major_announce_version();
1065 info->info102->version_minor = lp_minor_announce_version();
1066 info->info102->server_name = global_myname();
1067 info->info102->server_type = lp_default_server_announce();
1068 info->info102->userpath = "C:\\";
1069 info->info102->licenses = 10000;
1070 info->info102->anndelta = 3000;
1071 info->info102->disc = 0xf;
1072 info->info102->users = 0xffffffff;
1073 info->info102->hidden = 0;
1074 info->info102->announce = 240;
1075 info->info102->comment = lp_serverstring();
1078 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1079 info->info101->platform_id = 500;
1080 info->info101->server_name = global_myname();
1081 info->info101->version_major = lp_major_announce_version();
1082 info->info101->version_minor = lp_minor_announce_version();
1083 info->info101->server_type = lp_default_server_announce();
1084 info->info101->comment = lp_serverstring();
1087 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1088 info->info100->platform_id = 500;
1089 info->info100->server_name = global_myname();
1092 return WERR_UNKNOWN_LEVEL;
1096 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1101 /*******************************************************************
1103 ********************************************************************/
1105 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1107 /* Set up the net server set info structure. */
1112 /*******************************************************************
1114 ********************************************************************/
1116 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)
1118 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1123 return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1126 /*******************************************************************
1128 ********************************************************************/
1130 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)
1132 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1137 return init_srv_sess_info_ctr(p, ctr,
1143 /*******************************************************************
1145 ********************************************************************/
1147 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1149 struct sessionid *session_list;
1150 int num_sessions, snum;
1153 char *machine = talloc_strdup(p->mem_ctx, server_unc);
1155 /* strip leading backslashes if any */
1156 while (machine[0] == '\\') {
1157 memmove(machine, &machine[1], strlen(machine));
1160 num_sessions = list_sessions(&session_list);
1162 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1164 status = WERR_ACCESS_DENIED;
1166 /* fail out now if you are not root or not a domain admin */
1168 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1169 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1174 for (snum = 0; snum < num_sessions; snum++) {
1176 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1177 strequal(session_list[snum].remote_machine, machine)) {
1179 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1184 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1188 SAFE_FREE(session_list);
1193 /*******************************************************************
1195 ********************************************************************/
1197 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)
1199 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1201 if (!pipe_access_check(p)) {
1202 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1203 return WERR_ACCESS_DENIED;
1206 /* Create the list of shares for the response. */
1207 return init_srv_share_info_ctr(p, ctr, *level,
1208 resume_handle, totalentries, True);
1211 /*******************************************************************
1213 ********************************************************************/
1215 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)
1217 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1219 if (!pipe_access_check(p)) {
1220 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1221 return WERR_ACCESS_DENIED;
1224 /* Create the list of shares for the response. */
1225 return init_srv_share_info_ctr(p, ctr, *level,
1226 resume_handle, totalentries, False);
1229 /*******************************************************************
1231 ********************************************************************/
1233 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1235 const struct share_params *params;
1237 params = get_share_params(p->mem_ctx, share_name);
1239 if (params != NULL) {
1242 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1243 init_srv_share_info_0(p, info->info0,
1247 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1248 init_srv_share_info_1(p, info->info1,
1252 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1253 init_srv_share_info_2(p, info->info2,
1257 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1258 init_srv_share_info_501(p, info->info501,
1262 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1263 init_srv_share_info_502(p, info->info502,
1267 /* here for completeness */
1269 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1270 init_srv_share_info_1004(p, info->info1004,
1274 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1275 init_srv_share_info_1005(p, info->info1005,
1279 /* here for completeness 1006 - 1501 */
1281 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1282 init_srv_share_info_1006(p, info->info1006,
1286 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1287 init_srv_share_info_1007(p, info->info1007,
1291 info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1292 init_srv_share_info_1501(p, info->info1501,
1296 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1297 "switch value %d\n", level));
1298 return WERR_UNKNOWN_LEVEL;
1302 return WERR_INVALID_NAME;
1308 /*******************************************************************
1309 Check a given DOS pathname is valid for a share.
1310 ********************************************************************/
1312 char *valid_share_pathname(char *dos_pathname)
1316 /* Convert any '\' paths to '/' */
1317 unix_format(dos_pathname);
1318 unix_clean_name(dos_pathname);
1320 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1322 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1325 /* Only absolute paths allowed. */
1332 /*******************************************************************
1333 Net share set info. Modify share details.
1334 ********************************************************************/
1336 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)
1345 SEC_DESC *psd = NULL;
1346 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1347 BOOL is_disk_op = False;
1348 int max_connections = 0;
1349 fstring tmp_share_name;
1351 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1355 if ( strequal(share_name,"IPC$")
1356 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1357 || strequal(share_name,"global") )
1359 return WERR_ACCESS_DENIED;
1362 fstrcpy(tmp_share_name, share_name);
1363 snum = find_service(tmp_share_name);
1365 /* Does this share exist ? */
1367 return WERR_NET_NAME_NOT_FOUND;
1369 /* No change to printer shares. */
1370 if (lp_print_ok(snum))
1371 return WERR_ACCESS_DENIED;
1373 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1375 /* fail out now if you are not root and not a disk op */
1377 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1378 return WERR_ACCESS_DENIED;
1382 pstrcpy(pathname, lp_pathname(snum));
1383 pstrcpy(comment, info.info1->comment);
1384 type = info.info1->type;
1388 pstrcpy(comment, info.info2->comment);
1389 pstrcpy(pathname, info.info2->path);
1390 type = info.info2->type;
1391 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1395 /* not supported on set but here for completeness */
1397 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1398 type = q_u->info.share.info501.info_501.type;
1403 pstrcpy(comment, info.info502->comment);
1404 pstrcpy(pathname, info.info502->path);
1405 type = info.info502->type;
1406 psd = info.info502->sd;
1407 map_generic_share_sd_bits(psd);
1410 pstrcpy(pathname, lp_pathname(snum));
1411 pstrcpy(comment, info.info1004->comment);
1412 type = STYPE_DISKTREE;
1415 /* XP re-sets the csc policy even if it wasn't changed by the
1416 user, so we must compare it to see if it's what is set in
1417 smb.conf, so that we can contine other ops like setting
1419 if (((info.info1005->dfs_flags &
1420 SHARE_1005_CSC_POLICY_MASK) >>
1421 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1424 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1425 return WERR_ACCESS_DENIED;
1429 return WERR_ACCESS_DENIED;
1431 pstrcpy(pathname, lp_pathname(snum));
1432 pstrcpy(comment, lp_comment(snum));
1433 psd = info.info1501->sd;
1434 map_generic_share_sd_bits(psd);
1435 type = STYPE_DISKTREE;
1438 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1439 return WERR_UNKNOWN_LEVEL;
1442 /* We can only modify disk shares. */
1443 if (type != STYPE_DISKTREE)
1444 return WERR_ACCESS_DENIED;
1446 /* Check if the pathname is valid. */
1447 if (!(path = valid_share_pathname( pathname )))
1448 return WERR_OBJECT_PATH_INVALID;
1450 /* Ensure share name, pathname and comment don't contain '"' characters. */
1451 string_replace(tmp_share_name, '"', ' ');
1452 string_replace(path, '"', ' ');
1453 string_replace(comment, '"', ' ');
1455 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1456 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1458 /* Only call modify function if something changed. */
1460 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1461 || (lp_max_connections(snum) != max_connections) )
1463 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1464 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1465 return WERR_ACCESS_DENIED;
1468 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1469 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1471 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1473 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1478 if ( (ret = smbrun(command, NULL)) == 0 ) {
1479 /* Tell everyone we updated smb.conf. */
1480 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1486 /********* END SeDiskOperatorPrivilege BLOCK *********/
1488 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1491 return WERR_ACCESS_DENIED;
1493 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1496 /* Replace SD if changed. */
1501 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1504 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1505 if (!set_share_security(p->mem_ctx, share_name, psd))
1506 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1511 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1516 /*******************************************************************
1517 Net share add. Call 'add_share_command "sharename" "pathname"
1518 "comment" "max connections = "
1519 ********************************************************************/
1521 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1531 SEC_DESC *psd = NULL;
1532 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1534 int max_connections = 0;
1536 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1540 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1542 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1543 return WERR_ACCESS_DENIED;
1545 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1546 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1547 return WERR_ACCESS_DENIED;
1552 /* No path. Not enough info in a level 0 to do anything. */
1553 return WERR_ACCESS_DENIED;
1555 /* Not enough info in a level 1 to do anything. */
1556 return WERR_ACCESS_DENIED;
1558 pstrcpy(share_name, info.info2->name);
1559 pstrcpy(comment, info.info2->comment);
1560 pstrcpy(pathname, info.info2->path);
1561 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1562 type = info.info2->type;
1565 /* No path. Not enough info in a level 501 to do anything. */
1566 return WERR_ACCESS_DENIED;
1568 pstrcpy(share_name, info.info502->name);
1569 pstrcpy(comment, info.info502->comment);
1570 pstrcpy(pathname, info.info502->path);
1571 type = info.info502->type;
1572 psd = info.info502->sd;
1573 map_generic_share_sd_bits(psd);
1576 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1582 return WERR_ACCESS_DENIED;
1584 /* DFS only level. */
1585 return WERR_ACCESS_DENIED;
1587 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1588 return WERR_UNKNOWN_LEVEL;
1591 /* check for invalid share names */
1593 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1594 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1595 return WERR_INVALID_NAME;
1598 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1599 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1601 return WERR_ACCESS_DENIED;
1604 snum = find_service(share_name);
1606 /* Share already exists. */
1608 return WERR_ALREADY_EXISTS;
1610 /* We can only add disk shares. */
1611 if (type != STYPE_DISKTREE)
1612 return WERR_ACCESS_DENIED;
1614 /* Check if the pathname is valid. */
1615 if (!(path = valid_share_pathname( pathname )))
1616 return WERR_OBJECT_PATH_INVALID;
1618 /* Ensure share name, pathname and comment don't contain '"' characters. */
1619 string_replace(share_name, '"', ' ');
1620 string_replace(path, '"', ' ');
1621 string_replace(comment, '"', ' ');
1623 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1631 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1633 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1638 if ( (ret = smbrun(command, NULL)) == 0 ) {
1639 /* Tell everyone we updated smb.conf. */
1640 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1646 /********* END SeDiskOperatorPrivilege BLOCK *********/
1648 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1651 return WERR_ACCESS_DENIED;
1654 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1655 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1660 * We don't call reload_services() here, the message will
1661 * cause this to be done before the next packet is read
1662 * from the client. JRA.
1665 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1670 /*******************************************************************
1671 Net share delete. Call "delete share command" with the share name as
1673 ********************************************************************/
1675 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1680 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1682 fstring tmp_share_name;
1684 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1686 if ( strequal(share_name,"IPC$")
1687 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1688 || strequal(share_name,"global") )
1690 return WERR_ACCESS_DENIED;
1693 fstrcpy(tmp_share_name, share_name);
1694 snum = find_service(tmp_share_name);
1697 return WERR_NO_SUCH_SHARE;
1699 /* No change to printer shares. */
1700 if (lp_print_ok(snum))
1701 return WERR_ACCESS_DENIED;
1703 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1705 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1706 return WERR_ACCESS_DENIED;
1708 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1709 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1710 return WERR_ACCESS_DENIED;
1713 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1714 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1716 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1718 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1723 if ( (ret = smbrun(command, NULL)) == 0 ) {
1724 /* Tell everyone we updated smb.conf. */
1725 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1731 /********* END SeDiskOperatorPrivilege BLOCK *********/
1733 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1736 return WERR_ACCESS_DENIED;
1738 /* Delete the SD in the database. */
1739 delete_share_security(snum);
1741 lp_killservice(snum);
1746 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1748 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1750 return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1753 /*******************************************************************
1755 ********************************************************************/
1757 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1760 time_t unixdate = time(NULL);
1761 WERROR status = WERR_OK;
1763 /* We do this call first as if we do it *after* the gmtime call
1764 it overwrites the pointed-to values. JRA */
1766 uint32 zone = get_time_zone(unixdate)/60;
1768 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1770 t = gmtime(&unixdate);
1773 tod->elapsed = unixdate;
1775 tod->hours = t->tm_hour;
1776 tod->mins = t->tm_min;
1777 tod->secs = t->tm_sec;
1779 tod->timezone = zone;
1780 tod->tinterval = 10000;
1781 tod->day = t->tm_mday;
1782 tod->month = t->tm_mon + 1;
1783 tod->year = 1900+t->tm_year;
1784 tod->weekday = t->tm_wday;
1786 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1791 /***********************************************************************************
1792 Win9x NT tools get security descriptor.
1793 ***********************************************************************************/
1795 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)
1797 SEC_DESC *psd = NULL;
1800 files_struct *fsp = NULL;
1804 connection_struct *conn = NULL;
1805 BOOL became_user = False;
1806 WERROR status = WERR_OK;
1812 /* Null password is ok - we are already an authenticated user... */
1813 null_pw = data_blob(NULL, 0);
1816 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1820 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1821 status = ntstatus_to_werror(nt_status);
1825 if (!become_user(conn, conn->vuid)) {
1826 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1827 status = WERR_ACCESS_DENIED;
1832 pstrcpy(tmp_file, file);
1833 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1835 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1836 status = WERR_ACCESS_DENIED;
1840 if (!check_name(file,conn)) {
1841 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1842 status = WERR_ACCESS_DENIED;
1846 nt_status = open_file_stat(conn, file, &st, &fsp);
1847 if (!NT_STATUS_IS_OK(nt_status)) {
1848 /* Perhaps it is a directory */
1849 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1850 nt_status = open_directory(conn, file, &st,
1851 READ_CONTROL_ACCESS,
1852 FILE_SHARE_READ|FILE_SHARE_WRITE,
1857 if (!NT_STATUS_IS_OK(nt_status)) {
1858 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1859 status = WERR_ACCESS_DENIED;
1864 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1867 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1868 status = WERR_ACCESS_DENIED;
1872 sd_buf->sd_size= sd_size;
1875 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1877 close_file(fsp, NORMAL_CLOSE);
1879 close_cnum(conn, p->pipe_user.vuid);
1885 close_file(fsp, NORMAL_CLOSE);
1892 close_cnum(conn, p->pipe_user.vuid);
1897 /***********************************************************************************
1898 Win9x NT tools set security descriptor.
1899 ***********************************************************************************/
1901 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)
1905 files_struct *fsp = NULL;
1909 connection_struct *conn = NULL;
1910 BOOL became_user = False;
1911 WERROR status = WERR_OK;
1916 /* Null password is ok - we are already an authenticated user... */
1917 null_pw = data_blob(NULL, 0);
1920 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1924 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1925 status = ntstatus_to_werror(nt_status);
1929 if (!become_user(conn, conn->vuid)) {
1930 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1931 status = WERR_ACCESS_DENIED;
1936 pstrcpy(tmp_file, file);
1937 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1939 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1940 status = WERR_ACCESS_DENIED;
1944 if (!check_name(file,conn)) {
1945 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1946 status = WERR_ACCESS_DENIED;
1951 nt_status = open_file_stat(conn, file, &st, &fsp);
1953 if (!NT_STATUS_IS_OK(nt_status)) {
1954 /* Perhaps it is a directory */
1955 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1956 nt_status = open_directory(conn, file, &st,
1957 FILE_READ_ATTRIBUTES,
1958 FILE_SHARE_READ|FILE_SHARE_WRITE,
1963 if (!NT_STATUS_IS_OK(nt_status)) {
1964 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1965 status = WERR_ACCESS_DENIED;
1970 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1973 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1974 status = WERR_ACCESS_DENIED;
1978 close_file(fsp, NORMAL_CLOSE);
1980 close_cnum(conn, p->pipe_user.vuid);
1986 close_file(fsp, NORMAL_CLOSE);
1994 close_cnum(conn, p->pipe_user.vuid);
2000 /***********************************************************************************
2001 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2002 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2003 These disks would the disks listed by this function.
2004 Users could then create shares relative to these disks. Watch out for moving these disks around.
2005 "Nigel Williams" <nigel@veritas.com>.
2006 ***********************************************************************************/
2008 static const char *server_disks[] = {"C:"};
2010 static uint32 get_server_disk_count(void)
2012 return sizeof(server_disks)/sizeof(server_disks[0]);
2015 static uint32 init_server_disk_enum(uint32 *resume)
2017 uint32 server_disk_count = get_server_disk_count();
2019 /*resume can be an offset into the list for now*/
2021 if(*resume & 0x80000000)
2024 if(*resume > server_disk_count)
2025 *resume = server_disk_count;
2027 return server_disk_count - *resume;
2030 static const char *next_server_disk_enum(uint32 *resume)
2034 if(init_server_disk_enum(resume) == 0)
2037 disk = server_disks[*resume];
2041 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2046 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)
2049 const char *disk_name;
2051 WERROR status = WERR_OK;
2053 *totalentries = init_server_disk_enum(resume_handle);
2056 if(!(info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2060 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2062 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2067 /*copy disk name into a unicode string*/
2069 info->disks[i].disk = disk_name;
2072 /* add a terminating null string. Is this there if there is more data to come? */
2077 info->disks[i].disk = "";
2082 /********************************************************************
2083 ********************************************************************/
2085 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2089 if ((flags != 0x0) && (flags != 0x80000000)) {
2090 return WERR_INVALID_PARAM;
2093 switch ( name_type ) {
2095 len = strlen_m(name);
2097 if ((flags == 0x0) && (len > 81)) {
2098 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2099 return WERR_INVALID_NAME;
2101 if ((flags == 0x80000000) && (len > 13)) {
2102 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2103 return WERR_INVALID_NAME;
2106 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2107 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2108 return WERR_INVALID_NAME;
2113 return WERR_UNKNOWN_LEVEL;
2120 /********************************************************************
2121 ********************************************************************/
2123 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2125 return WERR_ACCESS_DENIED;
2128 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)
2130 return WERR_NOT_SUPPORTED;
2133 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2135 return WERR_NOT_SUPPORTED;
2138 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2140 return WERR_NOT_SUPPORTED;
2143 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)
2145 return WERR_NOT_SUPPORTED;
2148 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2150 return WERR_NOT_SUPPORTED;
2153 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)
2155 return WERR_NOT_SUPPORTED;
2158 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2160 return WERR_NOT_SUPPORTED;
2163 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2165 return WERR_NOT_SUPPORTED;
2168 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2170 return WERR_NOT_SUPPORTED;
2173 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2175 return WERR_NOT_SUPPORTED;
2178 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2180 return WERR_NOT_SUPPORTED;
2183 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2185 return WERR_NOT_SUPPORTED;
2188 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)
2190 return WERR_NOT_SUPPORTED;
2193 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2195 return WERR_NOT_SUPPORTED;
2198 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2200 return WERR_NOT_SUPPORTED;
2203 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2205 return WERR_NOT_SUPPORTED;
2208 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)
2210 return WERR_NOT_SUPPORTED;
2213 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2215 return WERR_NOT_SUPPORTED;
2218 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2220 return WERR_NOT_SUPPORTED;
2223 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2225 return WERR_NOT_SUPPORTED;
2228 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2230 return WERR_NOT_SUPPORTED;
2233 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2235 return WERR_NOT_SUPPORTED;
2238 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2240 return WERR_NOT_SUPPORTED;
2243 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)
2245 return WERR_NOT_SUPPORTED;
2248 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2250 return WERR_NOT_SUPPORTED;
2253 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2255 return WERR_NOT_SUPPORTED;
2258 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2260 return WERR_NOT_SUPPORTED;
2263 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2265 return WERR_NOT_SUPPORTED;
2268 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2270 return WERR_NOT_SUPPORTED;
2273 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2275 return WERR_NOT_SUPPORTED;
2278 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2280 return WERR_NOT_SUPPORTED;
2283 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2285 return WERR_NOT_SUPPORTED;
2288 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2290 return WERR_NOT_SUPPORTED;
2293 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2295 return WERR_NOT_SUPPORTED;
2298 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2300 return WERR_NOT_SUPPORTED;