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"));
515 /* Ensure all the usershares are loaded. */
517 load_usershare_shares();
522 if (!(shares = share_list_all(ctx))) {
523 DEBUG(5, ("Could not list shares\n"));
524 return WERR_ACCESS_DENIED;
527 switch (info_level) {
529 ctr->ctr0 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr0);
532 ctr->ctr1 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1);
535 ctr->ctr2 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr2);
538 ctr->ctr501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr501);
541 ctr->ctr502 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr502);
544 ctr->ctr1004 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1004);
547 ctr->ctr1005 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1005);
550 ctr->ctr1006 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1006);
553 ctr->ctr1007 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1007);
556 ctr->ctr1501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1501);
559 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
560 "value %d\n", info_level));
561 return WERR_UNKNOWN_LEVEL;
564 while ((share = next_share(shares)) != NULL) {
565 if (!lp_browseable(share->service)) {
568 if (!all_shares && is_hidden_share(share)) {
572 switch (info_level) {
575 struct srvsvc_NetShareInfo0 i;
576 init_srv_share_info_0(p, &i, share);
577 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
578 &ctr->ctr0->array, &ctr->ctr0->count);
579 if (ctr->ctr0->array == NULL) {
582 *total_entries = ctr->ctr0->count;
588 struct srvsvc_NetShareInfo1 i;
589 init_srv_share_info_1(p, &i, share);
590 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
591 &ctr->ctr1->array, &ctr->ctr1->count);
592 if (ctr->ctr1->array == NULL) {
595 *total_entries = ctr->ctr1->count;
601 struct srvsvc_NetShareInfo2 i;
602 init_srv_share_info_2(p, &i, share);
603 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
604 &ctr->ctr2->array, &ctr->ctr2->count);
605 if (ctr->ctr2->array == NULL) {
608 *total_entries = ctr->ctr2->count;
614 struct srvsvc_NetShareInfo501 i;
615 init_srv_share_info_501(p, &i, share);
616 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
617 &ctr->ctr501->array, &ctr->ctr501->count);
618 if (ctr->ctr501->array == NULL) {
621 *total_entries = ctr->ctr501->count;
627 struct srvsvc_NetShareInfo502 i;
628 init_srv_share_info_502(p, &i, share);
629 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
630 &ctr->ctr502->array, &ctr->ctr502->count);
631 if (ctr->ctr502->array == NULL) {
634 *total_entries = ctr->ctr502->count;
638 /* here for completeness but not currently used with enum
643 struct srvsvc_NetShareInfo1004 i;
644 init_srv_share_info_1004(p, &i, share);
645 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
646 &ctr->ctr1004->array, &ctr->ctr1004->count);
647 if (ctr->ctr1004->array == NULL) {
650 *total_entries = ctr->ctr1004->count;
656 struct srvsvc_NetShareInfo1005 i;
657 init_srv_share_info_1005(p, &i, share);
658 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
659 &ctr->ctr1005->array, &ctr->ctr1005->count);
660 if (ctr->ctr1005->array == NULL) {
663 *total_entries = ctr->ctr1005->count;
669 struct srvsvc_NetShareInfo1006 i;
670 init_srv_share_info_1006(p, &i, share);
671 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
672 &ctr->ctr1006->array, &ctr->ctr1006->count);
673 if (ctr->ctr1006->array == NULL) {
676 *total_entries = ctr->ctr1006->count;
682 struct srvsvc_NetShareInfo1007 i;
683 init_srv_share_info_1007(p, &i, share);
684 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
685 &ctr->ctr1007->array, &ctr->ctr1007->count);
686 if (ctr->ctr1007->array == NULL) {
689 *total_entries = ctr->ctr1007->count;
695 struct sec_desc_buf i;
696 init_srv_share_info_1501(p, &i, share);
697 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
698 &ctr->ctr1501->array, &ctr->ctr1501->count);
699 if (ctr->ctr1501->array == NULL) {
702 *total_entries = ctr->ctr1501->count;
713 /*******************************************************************
714 fill in a sess info level 0 structure.
715 ********************************************************************/
717 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
719 struct sessionid *session_list;
720 uint32 num_entries = 0;
721 (*stot) = list_sessions(&session_list);
727 SAFE_FREE(session_list);
731 DEBUG(5,("init_srv_sess_0_ss0\n"));
733 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
736 for (; (*snum) < (*stot); (*snum)++) {
737 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
741 ss0->count = num_entries;
743 if ((*snum) >= (*stot)) {
751 SAFE_FREE(session_list);
754 /*******************************************************************
755 ********************************************************************/
757 static void sess_file_fn( const struct share_mode_entry *e,
758 const char *sharepath, const char *fname,
761 struct sess_file_count *sess = (struct sess_file_count *)private_data;
763 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
770 /*******************************************************************
771 ********************************************************************/
773 static int net_count_files( uid_t uid, pid_t pid )
775 struct sess_file_count s_file_cnt;
777 s_file_cnt.count = 0;
778 s_file_cnt.uid = uid;
779 s_file_cnt.pid = pid;
781 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
783 return s_file_cnt.count;
786 /*******************************************************************
787 fill in a sess info level 1 structure.
788 ********************************************************************/
790 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
792 struct sessionid *session_list;
793 uint32 num_entries = 0;
794 time_t now = time(NULL);
810 (*stot) = list_sessions(&session_list);
812 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
814 for (; (*snum) < (*stot); (*snum)++) {
817 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
821 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
822 session_list[*snum].username));
826 connect_time = (uint32)(now - session_list[*snum].connect_start);
827 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
828 guest = strequal( session_list[*snum].username, lp_guestaccount() );
830 ss1->array[num_entries].client = session_list[*snum].remote_machine;
831 ss1->array[num_entries].user = session_list[*snum].username;
832 ss1->array[num_entries].num_open = num_files;
833 ss1->array[num_entries].time = connect_time;
834 ss1->array[num_entries].idle_time = 0;
835 ss1->array[num_entries].user_flags = guest;
840 ss1->count = num_entries;
842 if ((*snum) >= (*stot)) {
846 SAFE_FREE(session_list);
849 /*******************************************************************
850 makes a SRV_R_NET_SESS_ENUM structure.
851 ********************************************************************/
853 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
854 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
856 WERROR status = WERR_OK;
857 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
859 switch (switch_value) {
861 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
862 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
865 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
866 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
869 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
871 (*total_entries) = 0;
873 status = WERR_UNKNOWN_LEVEL;
880 /*******************************************************************
881 fill in a conn info level 0 structure.
882 ********************************************************************/
884 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
886 uint32 num_entries = 0;
894 DEBUG(5,("init_srv_conn_0_ss0\n"));
897 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
898 for (; (*snum) < (*stot); (*snum)++) {
900 ss0->array[num_entries].conn_id = (*stot);
902 /* move on to creating next connection */
903 /* move on to creating next conn */
907 ss0->count = num_entries;
909 if ((*snum) >= (*stot)) {
921 /*******************************************************************
922 fill in a conn info level 1 structure.
923 ********************************************************************/
925 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
927 uint32 num_entries = 0;
935 DEBUG(5,("init_srv_conn_1_ss1\n"));
938 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
939 for (; (*snum) < (*stot); (*snum)++) {
940 ss1->array[num_entries].conn_id = (*stot);
941 ss1->array[num_entries].conn_type = 0x3;
942 ss1->array[num_entries].num_open = 1;
943 ss1->array[num_entries].num_users = 1;
944 ss1->array[num_entries].conn_time = 3;
945 ss1->array[num_entries].user = "dummy_user";
946 ss1->array[num_entries].share = "IPC$";
948 /* move on to creating next connection */
949 /* move on to creating next conn */
953 ss1->count = num_entries;
955 if ((*snum) >= (*stot)) {
967 /*******************************************************************
968 makes a SRV_R_NET_CONN_ENUM structure.
969 ********************************************************************/
971 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
972 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
974 WERROR status = WERR_OK;
975 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
977 switch (switch_value) {
979 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
982 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
985 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
988 (*total_entries) = 0;
989 status = WERR_UNKNOWN_LEVEL;
996 /*******************************************************************
997 makes a SRV_R_NET_FILE_ENUM structure.
998 ********************************************************************/
1000 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1002 TALLOC_CTX *ctx = get_talloc_ctx();
1005 /* TODO -- Windows enumerates
1007 (c) open directories and files */
1009 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1011 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1012 if ( !W_ERROR_IS_OK(status))
1015 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1016 if ( !W_ERROR_IS_OK(status))
1019 ctr->ctr3->count = *num_entries;
1024 /*******************************************************************
1025 *******************************************************************/
1027 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)
1031 return net_file_enum_3(p, ctr, resume_handle, totalentries );
1033 return WERR_UNKNOWN_LEVEL;
1039 /*******************************************************************
1041 ********************************************************************/
1043 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1045 WERROR status = WERR_OK;
1049 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1051 if (!pipe_access_check(p)) {
1052 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1053 return WERR_ACCESS_DENIED;
1058 /* Technically level 102 should only be available to
1059 Administrators but there isn't anything super-secret
1060 here, as most of it is made up. */
1063 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1065 info->info102->platform_id = 500;
1066 info->info102->version_major = lp_major_announce_version();
1067 info->info102->version_minor = lp_minor_announce_version();
1068 info->info102->server_name = global_myname();
1069 info->info102->server_type = lp_default_server_announce();
1070 info->info102->userpath = "C:\\";
1071 info->info102->licenses = 10000;
1072 info->info102->anndelta = 3000;
1073 info->info102->disc = 0xf;
1074 info->info102->users = 0xffffffff;
1075 info->info102->hidden = 0;
1076 info->info102->announce = 240;
1077 info->info102->comment = lp_serverstring();
1080 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1081 info->info101->platform_id = 500;
1082 info->info101->server_name = global_myname();
1083 info->info101->version_major = lp_major_announce_version();
1084 info->info101->version_minor = lp_minor_announce_version();
1085 info->info101->server_type = lp_default_server_announce();
1086 info->info101->comment = lp_serverstring();
1089 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1090 info->info100->platform_id = 500;
1091 info->info100->server_name = global_myname();
1094 return WERR_UNKNOWN_LEVEL;
1098 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1103 /*******************************************************************
1105 ********************************************************************/
1107 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1109 /* Set up the net server set info structure. */
1114 /*******************************************************************
1116 ********************************************************************/
1118 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)
1120 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1125 return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1128 /*******************************************************************
1130 ********************************************************************/
1132 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)
1134 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1139 return init_srv_sess_info_ctr(p, ctr,
1145 /*******************************************************************
1147 ********************************************************************/
1149 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1151 struct sessionid *session_list;
1152 int num_sessions, snum;
1155 char *machine = talloc_strdup(p->mem_ctx, server_unc);
1157 /* strip leading backslashes if any */
1158 while (machine[0] == '\\') {
1159 memmove(machine, &machine[1], strlen(machine));
1162 num_sessions = list_sessions(&session_list);
1164 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1166 status = WERR_ACCESS_DENIED;
1168 /* fail out now if you are not root or not a domain admin */
1170 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1171 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1176 for (snum = 0; snum < num_sessions; snum++) {
1178 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1179 strequal(session_list[snum].remote_machine, machine)) {
1181 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1186 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1190 SAFE_FREE(session_list);
1195 /*******************************************************************
1197 ********************************************************************/
1199 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)
1201 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1203 if (!pipe_access_check(p)) {
1204 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1205 return WERR_ACCESS_DENIED;
1208 /* Create the list of shares for the response. */
1209 return init_srv_share_info_ctr(p, ctr, *level,
1210 resume_handle, totalentries, True);
1213 /*******************************************************************
1215 ********************************************************************/
1217 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)
1219 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1221 if (!pipe_access_check(p)) {
1222 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1223 return WERR_ACCESS_DENIED;
1226 /* Create the list of shares for the response. */
1227 return init_srv_share_info_ctr(p, ctr, *level,
1228 resume_handle, totalentries, False);
1231 /*******************************************************************
1233 ********************************************************************/
1235 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1237 const struct share_params *params;
1239 params = get_share_params(p->mem_ctx, share_name);
1241 if (params != NULL) {
1244 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1245 init_srv_share_info_0(p, info->info0,
1249 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1250 init_srv_share_info_1(p, info->info1,
1254 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1255 init_srv_share_info_2(p, info->info2,
1259 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1260 init_srv_share_info_501(p, info->info501,
1264 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1265 init_srv_share_info_502(p, info->info502,
1269 /* here for completeness */
1271 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1272 init_srv_share_info_1004(p, info->info1004,
1276 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1277 init_srv_share_info_1005(p, info->info1005,
1281 /* here for completeness 1006 - 1501 */
1283 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1284 init_srv_share_info_1006(p, info->info1006,
1288 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1289 init_srv_share_info_1007(p, info->info1007,
1293 info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1294 init_srv_share_info_1501(p, info->info1501,
1298 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1299 "switch value %d\n", level));
1300 return WERR_UNKNOWN_LEVEL;
1304 return WERR_INVALID_NAME;
1310 /*******************************************************************
1311 Check a given DOS pathname is valid for a share.
1312 ********************************************************************/
1314 char *valid_share_pathname(char *dos_pathname)
1318 /* Convert any '\' paths to '/' */
1319 unix_format(dos_pathname);
1320 unix_clean_name(dos_pathname);
1322 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1324 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1327 /* Only absolute paths allowed. */
1334 /*******************************************************************
1335 Net share set info. Modify share details.
1336 ********************************************************************/
1338 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)
1347 SEC_DESC *psd = NULL;
1348 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1349 BOOL is_disk_op = False;
1350 int max_connections = 0;
1351 fstring tmp_share_name;
1353 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1357 if ( strequal(share_name,"IPC$")
1358 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1359 || strequal(share_name,"global") )
1361 return WERR_ACCESS_DENIED;
1364 fstrcpy(tmp_share_name, share_name);
1365 snum = find_service(tmp_share_name);
1367 /* Does this share exist ? */
1369 return WERR_NET_NAME_NOT_FOUND;
1371 /* No change to printer shares. */
1372 if (lp_print_ok(snum))
1373 return WERR_ACCESS_DENIED;
1375 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1377 /* fail out now if you are not root and not a disk op */
1379 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1380 return WERR_ACCESS_DENIED;
1384 pstrcpy(pathname, lp_pathname(snum));
1385 pstrcpy(comment, info.info1->comment);
1386 type = info.info1->type;
1390 pstrcpy(comment, info.info2->comment);
1391 pstrcpy(pathname, info.info2->path);
1392 type = info.info2->type;
1393 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1397 /* not supported on set but here for completeness */
1399 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1400 type = q_u->info.share.info501.info_501.type;
1405 pstrcpy(comment, info.info502->comment);
1406 pstrcpy(pathname, info.info502->path);
1407 type = info.info502->type;
1408 psd = info.info502->sd;
1409 map_generic_share_sd_bits(psd);
1412 pstrcpy(pathname, lp_pathname(snum));
1413 pstrcpy(comment, info.info1004->comment);
1414 type = STYPE_DISKTREE;
1417 /* XP re-sets the csc policy even if it wasn't changed by the
1418 user, so we must compare it to see if it's what is set in
1419 smb.conf, so that we can contine other ops like setting
1421 if (((info.info1005->dfs_flags &
1422 SHARE_1005_CSC_POLICY_MASK) >>
1423 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1426 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1427 return WERR_ACCESS_DENIED;
1431 return WERR_ACCESS_DENIED;
1433 pstrcpy(pathname, lp_pathname(snum));
1434 pstrcpy(comment, lp_comment(snum));
1435 psd = info.info1501->sd;
1436 map_generic_share_sd_bits(psd);
1437 type = STYPE_DISKTREE;
1440 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1441 return WERR_UNKNOWN_LEVEL;
1444 /* We can only modify disk shares. */
1445 if (type != STYPE_DISKTREE)
1446 return WERR_ACCESS_DENIED;
1448 /* Check if the pathname is valid. */
1449 if (!(path = valid_share_pathname( pathname )))
1450 return WERR_OBJECT_PATH_INVALID;
1452 /* Ensure share name, pathname and comment don't contain '"' characters. */
1453 string_replace(tmp_share_name, '"', ' ');
1454 string_replace(path, '"', ' ');
1455 string_replace(comment, '"', ' ');
1457 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1458 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1460 /* Only call modify function if something changed. */
1462 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1463 || (lp_max_connections(snum) != max_connections) )
1465 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1466 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1467 return WERR_ACCESS_DENIED;
1470 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1471 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1473 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1475 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1480 if ( (ret = smbrun(command, NULL)) == 0 ) {
1481 /* Tell everyone we updated smb.conf. */
1482 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1488 /********* END SeDiskOperatorPrivilege BLOCK *********/
1490 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1493 return WERR_ACCESS_DENIED;
1495 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1498 /* Replace SD if changed. */
1503 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1506 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1507 if (!set_share_security(p->mem_ctx, share_name, psd))
1508 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1513 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1518 /*******************************************************************
1519 Net share add. Call 'add_share_command "sharename" "pathname"
1520 "comment" "max connections = "
1521 ********************************************************************/
1523 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1533 SEC_DESC *psd = NULL;
1534 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1536 int max_connections = 0;
1538 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1542 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1544 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1545 return WERR_ACCESS_DENIED;
1547 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1548 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1549 return WERR_ACCESS_DENIED;
1554 /* No path. Not enough info in a level 0 to do anything. */
1555 return WERR_ACCESS_DENIED;
1557 /* Not enough info in a level 1 to do anything. */
1558 return WERR_ACCESS_DENIED;
1560 pstrcpy(share_name, info.info2->name);
1561 pstrcpy(comment, info.info2->comment);
1562 pstrcpy(pathname, info.info2->path);
1563 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1564 type = info.info2->type;
1567 /* No path. Not enough info in a level 501 to do anything. */
1568 return WERR_ACCESS_DENIED;
1570 pstrcpy(share_name, info.info502->name);
1571 pstrcpy(comment, info.info502->comment);
1572 pstrcpy(pathname, info.info502->path);
1573 type = info.info502->type;
1574 psd = info.info502->sd;
1575 map_generic_share_sd_bits(psd);
1578 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1584 return WERR_ACCESS_DENIED;
1586 /* DFS only level. */
1587 return WERR_ACCESS_DENIED;
1589 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1590 return WERR_UNKNOWN_LEVEL;
1593 /* check for invalid share names */
1595 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1596 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1597 return WERR_INVALID_NAME;
1600 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1601 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1603 return WERR_ACCESS_DENIED;
1606 snum = find_service(share_name);
1608 /* Share already exists. */
1610 return WERR_ALREADY_EXISTS;
1612 /* We can only add disk shares. */
1613 if (type != STYPE_DISKTREE)
1614 return WERR_ACCESS_DENIED;
1616 /* Check if the pathname is valid. */
1617 if (!(path = valid_share_pathname( pathname )))
1618 return WERR_OBJECT_PATH_INVALID;
1620 /* Ensure share name, pathname and comment don't contain '"' characters. */
1621 string_replace(share_name, '"', ' ');
1622 string_replace(path, '"', ' ');
1623 string_replace(comment, '"', ' ');
1625 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1633 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1635 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1640 if ( (ret = smbrun(command, NULL)) == 0 ) {
1641 /* Tell everyone we updated smb.conf. */
1642 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1648 /********* END SeDiskOperatorPrivilege BLOCK *********/
1650 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1653 return WERR_ACCESS_DENIED;
1656 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1657 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1662 * We don't call reload_services() here, the message will
1663 * cause this to be done before the next packet is read
1664 * from the client. JRA.
1667 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1672 /*******************************************************************
1673 Net share delete. Call "delete share command" with the share name as
1675 ********************************************************************/
1677 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1682 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1684 fstring tmp_share_name;
1686 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1688 if ( strequal(share_name,"IPC$")
1689 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1690 || strequal(share_name,"global") )
1692 return WERR_ACCESS_DENIED;
1695 fstrcpy(tmp_share_name, share_name);
1696 snum = find_service(tmp_share_name);
1699 return WERR_NO_SUCH_SHARE;
1701 /* No change to printer shares. */
1702 if (lp_print_ok(snum))
1703 return WERR_ACCESS_DENIED;
1705 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1707 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1708 return WERR_ACCESS_DENIED;
1710 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1711 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1712 return WERR_ACCESS_DENIED;
1715 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1716 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1718 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1720 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1725 if ( (ret = smbrun(command, NULL)) == 0 ) {
1726 /* Tell everyone we updated smb.conf. */
1727 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1733 /********* END SeDiskOperatorPrivilege BLOCK *********/
1735 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1738 return WERR_ACCESS_DENIED;
1740 /* Delete the SD in the database. */
1741 delete_share_security(snum);
1743 lp_killservice(snum);
1748 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1750 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1752 return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1755 /*******************************************************************
1757 ********************************************************************/
1759 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1762 time_t unixdate = time(NULL);
1763 WERROR status = WERR_OK;
1765 /* We do this call first as if we do it *after* the gmtime call
1766 it overwrites the pointed-to values. JRA */
1768 uint32 zone = get_time_zone(unixdate)/60;
1770 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1772 t = gmtime(&unixdate);
1775 tod->elapsed = unixdate;
1777 tod->hours = t->tm_hour;
1778 tod->mins = t->tm_min;
1779 tod->secs = t->tm_sec;
1781 tod->timezone = zone;
1782 tod->tinterval = 10000;
1783 tod->day = t->tm_mday;
1784 tod->month = t->tm_mon + 1;
1785 tod->year = 1900+t->tm_year;
1786 tod->weekday = t->tm_wday;
1788 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1793 /***********************************************************************************
1794 Win9x NT tools get security descriptor.
1795 ***********************************************************************************/
1797 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)
1799 SEC_DESC *psd = NULL;
1802 files_struct *fsp = NULL;
1806 connection_struct *conn = NULL;
1807 BOOL became_user = False;
1808 WERROR status = WERR_OK;
1814 /* Null password is ok - we are already an authenticated user... */
1815 null_pw = data_blob(NULL, 0);
1818 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1822 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1823 status = ntstatus_to_werror(nt_status);
1827 if (!become_user(conn, conn->vuid)) {
1828 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1829 status = WERR_ACCESS_DENIED;
1834 pstrcpy(tmp_file, file);
1835 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1837 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1838 status = WERR_ACCESS_DENIED;
1842 if (!check_name(file,conn)) {
1843 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1844 status = WERR_ACCESS_DENIED;
1848 nt_status = open_file_stat(conn, file, &st, &fsp);
1849 if (!NT_STATUS_IS_OK(nt_status)) {
1850 /* Perhaps it is a directory */
1851 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1852 nt_status = open_directory(conn, file, &st,
1853 READ_CONTROL_ACCESS,
1854 FILE_SHARE_READ|FILE_SHARE_WRITE,
1859 if (!NT_STATUS_IS_OK(nt_status)) {
1860 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1861 status = WERR_ACCESS_DENIED;
1866 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1869 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1870 status = WERR_ACCESS_DENIED;
1874 sd_buf->sd_size= sd_size;
1877 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1879 close_file(fsp, NORMAL_CLOSE);
1881 close_cnum(conn, p->pipe_user.vuid);
1887 close_file(fsp, NORMAL_CLOSE);
1894 close_cnum(conn, p->pipe_user.vuid);
1899 /***********************************************************************************
1900 Win9x NT tools set security descriptor.
1901 ***********************************************************************************/
1903 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)
1907 files_struct *fsp = NULL;
1911 connection_struct *conn = NULL;
1912 BOOL became_user = False;
1913 WERROR status = WERR_OK;
1918 /* Null password is ok - we are already an authenticated user... */
1919 null_pw = data_blob(NULL, 0);
1922 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1926 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1927 status = ntstatus_to_werror(nt_status);
1931 if (!become_user(conn, conn->vuid)) {
1932 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1933 status = WERR_ACCESS_DENIED;
1938 pstrcpy(tmp_file, file);
1939 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1941 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1942 status = WERR_ACCESS_DENIED;
1946 if (!check_name(file,conn)) {
1947 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1948 status = WERR_ACCESS_DENIED;
1953 nt_status = open_file_stat(conn, file, &st, &fsp);
1955 if (!NT_STATUS_IS_OK(nt_status)) {
1956 /* Perhaps it is a directory */
1957 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1958 nt_status = open_directory(conn, file, &st,
1959 FILE_READ_ATTRIBUTES,
1960 FILE_SHARE_READ|FILE_SHARE_WRITE,
1965 if (!NT_STATUS_IS_OK(nt_status)) {
1966 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1967 status = WERR_ACCESS_DENIED;
1972 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1975 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1976 status = WERR_ACCESS_DENIED;
1980 close_file(fsp, NORMAL_CLOSE);
1982 close_cnum(conn, p->pipe_user.vuid);
1988 close_file(fsp, NORMAL_CLOSE);
1996 close_cnum(conn, p->pipe_user.vuid);
2002 /***********************************************************************************
2003 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2004 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2005 These disks would the disks listed by this function.
2006 Users could then create shares relative to these disks. Watch out for moving these disks around.
2007 "Nigel Williams" <nigel@veritas.com>.
2008 ***********************************************************************************/
2010 static const char *server_disks[] = {"C:"};
2012 static uint32 get_server_disk_count(void)
2014 return sizeof(server_disks)/sizeof(server_disks[0]);
2017 static uint32 init_server_disk_enum(uint32 *resume)
2019 uint32 server_disk_count = get_server_disk_count();
2021 /*resume can be an offset into the list for now*/
2023 if(*resume & 0x80000000)
2026 if(*resume > server_disk_count)
2027 *resume = server_disk_count;
2029 return server_disk_count - *resume;
2032 static const char *next_server_disk_enum(uint32 *resume)
2036 if(init_server_disk_enum(resume) == 0)
2039 disk = server_disks[*resume];
2043 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2048 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)
2051 const char *disk_name;
2053 WERROR status = WERR_OK;
2055 *totalentries = init_server_disk_enum(resume_handle);
2058 if(!(info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2062 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2064 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2069 /*copy disk name into a unicode string*/
2071 info->disks[i].disk = disk_name;
2074 /* add a terminating null string. Is this there if there is more data to come? */
2079 info->disks[i].disk = "";
2084 /********************************************************************
2085 ********************************************************************/
2087 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2091 if ((flags != 0x0) && (flags != 0x80000000)) {
2092 return WERR_INVALID_PARAM;
2095 switch ( name_type ) {
2097 len = strlen_m(name);
2099 if ((flags == 0x0) && (len > 81)) {
2100 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2101 return WERR_INVALID_NAME;
2103 if ((flags == 0x80000000) && (len > 13)) {
2104 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2105 return WERR_INVALID_NAME;
2108 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2109 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2110 return WERR_INVALID_NAME;
2115 return WERR_UNKNOWN_LEVEL;
2122 /********************************************************************
2123 ********************************************************************/
2125 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2127 return WERR_ACCESS_DENIED;
2130 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)
2132 return WERR_NOT_SUPPORTED;
2135 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2137 return WERR_NOT_SUPPORTED;
2140 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2142 return WERR_NOT_SUPPORTED;
2145 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)
2147 return WERR_NOT_SUPPORTED;
2150 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2152 return WERR_NOT_SUPPORTED;
2155 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)
2157 return WERR_NOT_SUPPORTED;
2160 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2162 return WERR_NOT_SUPPORTED;
2165 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2167 return WERR_NOT_SUPPORTED;
2170 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2172 return WERR_NOT_SUPPORTED;
2175 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2177 return WERR_NOT_SUPPORTED;
2180 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2182 return WERR_NOT_SUPPORTED;
2185 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2187 return WERR_NOT_SUPPORTED;
2190 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)
2192 return WERR_NOT_SUPPORTED;
2195 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2197 return WERR_NOT_SUPPORTED;
2200 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2202 return WERR_NOT_SUPPORTED;
2205 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2207 return WERR_NOT_SUPPORTED;
2210 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)
2212 return WERR_NOT_SUPPORTED;
2215 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2217 return WERR_NOT_SUPPORTED;
2220 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2222 return WERR_NOT_SUPPORTED;
2225 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2227 return WERR_NOT_SUPPORTED;
2230 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2232 return WERR_NOT_SUPPORTED;
2235 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2237 return WERR_NOT_SUPPORTED;
2240 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2242 return WERR_NOT_SUPPORTED;
2245 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)
2247 return WERR_NOT_SUPPORTED;
2250 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2252 return WERR_NOT_SUPPORTED;
2255 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2257 return WERR_NOT_SUPPORTED;
2260 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2262 return WERR_NOT_SUPPORTED;
2265 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2267 return WERR_NOT_SUPPORTED;
2270 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2272 return WERR_NOT_SUPPORTED;
2275 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2277 return WERR_NOT_SUPPORTED;
2280 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2282 return WERR_NOT_SUPPORTED;
2285 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2287 return WERR_NOT_SUPPORTED;
2290 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2292 return WERR_NOT_SUPPORTED;
2295 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2297 return WERR_NOT_SUPPORTED;
2300 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2302 return WERR_NOT_SUPPORTED;