The Samba-Bugzilla – Attachment 4989 Details for
Bug 6592
Samba server does not respond properly to NetWkstaGetInfo and NetWkstaUserEnum requests
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for Samba 3.4 versions
samba-3.4.2-netwksta.patch (text/plain), 24.37 KB, created by
Ian Puleston
on 2009-11-23 19:57:04 UTC
(
hide
)
Description:
Patch for Samba 3.4 versions
Filename:
MIME Type:
Creator:
Ian Puleston
Created:
2009-11-23 19:57:04 UTC
Size:
24.37 KB
patch
obsolete
>From 1fec53d92e2856ac1ca385881792ddcad633b6aa Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 3 Aug 2009 16:52:01 +0200 >Subject: [PATCH 1/3] s3: Support NetWkstaGetInfo 101 and 102 > >--- > source3/configure.in | 2 +- > source3/rpc_server/srv_wkssvc_nt.c | 128 +++++++++++++++++++++++++++++++---- > 2 files changed, 114 insertions(+), 16 deletions(-) > >diff --git a/source3/configure.in b/source3/configure.in >index aab8c01..793fd67 100644 >--- a/source3/configure.in >+++ b/source3/configure.in >@@ -2086,7 +2086,7 @@ dnl We need to check for many of them > dnl But we don't need to do each and every one, because our code uses > dnl mostly just the utmp (not utmpx) fields. > >-AC_CHECK_FUNCS(pututline pututxline updwtmp updwtmpx getutmpx) >+AC_CHECK_FUNCS(pututline pututxline updwtmp updwtmpx getutmpx getutxent) > > AC_CACHE_CHECK([for ut_name in utmp],samba_cv_HAVE_UT_UT_NAME,[ > AC_TRY_COMPILE([#include <sys/types.h> >diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c >index ab09e86..0bc92ac 100644 >--- a/source3/rpc_server/srv_wkssvc_nt.c >+++ b/source3/rpc_server/srv_wkssvc_nt.c >@@ -29,12 +29,54 @@ > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_RPC_SRV > >+#ifdef HAVE_GETUTXENT >+ >+#include <utmpx.h> >+ >+static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) >+{ >+ char **users = NULL; >+ int num_users = 0; >+ struct utmpx *u; >+ >+ while ((u = getutxent()) != NULL) { >+ char **tmp; >+ tmp = talloc_realloc(mem_ctx, users, char *, num_users+1); >+ if (tmp == NULL) { >+ return NULL; >+ } >+ users = tmp; >+ users[num_users] = talloc_strdup(users, u->ut_user); >+ if (users[num_users] == NULL) { >+ TALLOC_FREE(users); >+ return NULL; >+ } >+ } >+ return users; >+} >+ >+#else >+ >+static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) >+{ >+ return NULL; >+} >+ >+#endif >+ > /******************************************************************* > Fill in the values for the struct wkssvc_NetWkstaInfo100. > ********************************************************************/ > >-static void create_wks_info_100(struct wkssvc_NetWkstaInfo100 *info100) >+static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx) > { >+ struct wkssvc_NetWkstaInfo100 *info100; >+ >+ info100 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo100); >+ if (info100 == NULL) { >+ return NULL; >+ } >+ > info100->platform_id = PLATFORM_ID_NT; /* unknown */ > info100->version_major = lp_major_announce_version(); > info100->version_minor = lp_minor_announce_version(); >@@ -44,7 +86,56 @@ static void create_wks_info_100(struct wkssvc_NetWkstaInfo100 *info100) > info100->domain_name = talloc_asprintf_strupper_m( > info100, "%s", lp_workgroup()); > >- return; >+ return info100; >+} >+ >+static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaInfo101 *info101; >+ >+ info101 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo101); >+ if (info101 == NULL) { >+ return NULL; >+ } >+ >+ info101->platform_id = PLATFORM_ID_NT; /* unknown */ >+ info101->version_major = lp_major_announce_version(); >+ info101->version_minor = lp_minor_announce_version(); >+ >+ info101->server_name = talloc_asprintf_strupper_m( >+ info101, "%s", global_myname()); >+ info101->domain_name = talloc_asprintf_strupper_m( >+ info101, "%s", lp_workgroup()); >+ info101->lan_root = NULL; >+ >+ return info101; >+} >+ >+static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaInfo102 *info102; >+ char **users; >+ >+ info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102); >+ if (info102 == NULL) { >+ return NULL; >+ } >+ >+ info102->platform_id = PLATFORM_ID_NT; /* unknown */ >+ info102->version_major = lp_major_announce_version(); >+ info102->version_minor = lp_minor_announce_version(); >+ >+ info102->server_name = talloc_asprintf_strupper_m( >+ info102, "%s", global_myname()); >+ info102->domain_name = talloc_asprintf_strupper_m( >+ info102, "%s", lp_workgroup()); >+ info102->lan_root = NULL; >+ >+ users = get_logged_on_userlist(talloc_tos()); >+ info102->logged_on_users = talloc_array_length(users); >+ TALLOC_FREE(users); >+ >+ return info102; > } > > /******************************************************************** >@@ -53,22 +144,29 @@ static void create_wks_info_100(struct wkssvc_NetWkstaInfo100 *info100) > > WERROR _wkssvc_NetWkstaGetInfo(pipes_struct *p, struct wkssvc_NetWkstaGetInfo *r) > { >- struct wkssvc_NetWkstaInfo100 *wks100 = NULL; >- >- /* We only support info level 100 currently */ >- >- if ( r->in.level != 100 ) { >+ switch (r->in.level) { >+ case 100: >+ r->out.info->info100 = create_wks_info_100(p->mem_ctx); >+ if (r->out.info->info100 == NULL) { >+ return WERR_NOMEM; >+ } >+ break; >+ case 101: >+ r->out.info->info101 = create_wks_info_101(p->mem_ctx); >+ if (r->out.info->info101 == NULL) { >+ return WERR_NOMEM; >+ } >+ break; >+ case 102: >+ r->out.info->info102 = create_wks_info_102(p->mem_ctx); >+ if (r->out.info->info102 == NULL) { >+ return WERR_NOMEM; >+ } >+ break; >+ default: > return WERR_UNKNOWN_LEVEL; > } > >- if ( (wks100 = TALLOC_ZERO_P(p->mem_ctx, struct wkssvc_NetWkstaInfo100)) == NULL ) { >- return WERR_NOMEM; >- } >- >- create_wks_info_100( wks100 ); >- >- r->out.info->info100 = wks100; >- > return WERR_OK; > } > >-- >1.6.0.1 > > >From 8e6dc9473ceaee86410112dea6a197b32ca39984 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 3 Aug 2009 17:27:11 +0200 >Subject: [PATCH 2/3] s3: First cut at _wkssvc_NetWkstaEnumUsers > >This needs access checks! >--- > source3/rpc_server/srv_wkssvc_nt.c | 55 ++++++++++++++++++++++++++++++++++-- > 1 files changed, 52 insertions(+), 3 deletions(-) > >diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c >index 0bc92ac..683de20 100644 >--- a/source3/rpc_server/srv_wkssvc_nt.c >+++ b/source3/rpc_server/srv_wkssvc_nt.c >@@ -41,6 +41,9 @@ static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) > > while ((u = getutxent()) != NULL) { > char **tmp; >+ if (u->ut_type != USER_PROCESS) { >+ continue; >+ } > tmp = talloc_realloc(mem_ctx, users, char *, num_users+1); > if (tmp == NULL) { > return NULL; >@@ -51,6 +54,7 @@ static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) > TALLOC_FREE(users); > return NULL; > } >+ num_users += 1; > } > return users; > } >@@ -180,14 +184,59 @@ WERROR _wkssvc_NetWkstaSetInfo(pipes_struct *p, struct wkssvc_NetWkstaSetInfo *r > return WERR_NOT_SUPPORTED; > } > >+static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( >+ TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0; >+ char **users; >+ int i, num_users; >+ >+ ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0); >+ if (ctr0 == NULL) { >+ return NULL; >+ } >+ >+ users = get_logged_on_userlist(talloc_tos()); >+ if (users == NULL) { >+ TALLOC_FREE(ctr0); >+ return NULL; >+ } >+ >+ num_users = talloc_array_length(users); >+ ctr0->entries_read = num_users; >+ ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0, >+ num_users); >+ if (ctr0->user0 == NULL) { >+ TALLOC_FREE(ctr0); >+ TALLOC_FREE(users); >+ return NULL; >+ } >+ >+ for (i=0; i<num_users; i++) { >+ ctr0->user0[i].user_name = talloc_move(ctr0->user0, &users[i]); >+ } >+ TALLOC_FREE(users); >+ return ctr0; >+} >+ > /******************************************************************** > ********************************************************************/ > > WERROR _wkssvc_NetWkstaEnumUsers(pipes_struct *p, struct wkssvc_NetWkstaEnumUsers *r) > { >- /* FIXME: Add implementation code here */ >- p->rng_fault_state = True; >- return WERR_NOT_SUPPORTED; >+ if (r->in.info->level != 0) { >+ return WERR_UNKNOWN_LEVEL; >+ } >+ >+ r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx); >+ if (r->out.info->ctr.user0 == NULL) { >+ return WERR_NOMEM; >+ } >+ r->out.info->level = r->in.info->level; >+ *r->out.entries_read = r->out.info->ctr.user0->entries_read; >+ *r->out.resume_handle = 0; >+ >+ return WERR_OK; > } > > /******************************************************************** >-- >1.6.2.1 > > >From 951a5ed9d0f9ae8ac12937c2ed1c79fc65f830dd Mon Sep 17 00:00:00 2001 >From: Ian Puleston <ipuleston@sonicwall.com> >Date: Fri, 30 Oct 2009 00:00:00 +0100 >Subject: [PATCH 3/3] s3: Complete support for NetWkstaGetInfo/NetWkstaEnumUsers > >--- >diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c >index 27a0253..7c13b5e 100644 >--- a/source3/rpc_server/srv_wkssvc_nt.c >+++ b/source3/rpc_server/srv_wkssvc_nt.c >@@ -28,33 +28,96 @@ > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_RPC_SRV > >+struct dom_usr { >+ char *name; >+ char *domain; >+ time_t login_time; >+}; >+ > #ifdef HAVE_GETUTXENT > > #include <utmpx.h> > >+struct usrinfo { >+ char *name; >+ struct timeval login_time; >+}; >+ >+static int usr_info_cmp(const void *p1, const void *p2) >+{ >+ const struct usrinfo *usr1 = (const struct usrinfo *)p1; >+ const struct usrinfo *usr2 = (const struct usrinfo *)p2; >+ >+ /* Called from qsort to compare two users in a usrinfo_t array for >+ * sorting by login time. Return >0 if usr1 login time was later than >+ * usr2 login time, <0 if it was earlier */ >+ return ((usr1->login_time.tv_sec == usr2->login_time.tv_sec) >+ ? usr1->login_time.tv_usec - usr2->login_time.tv_usec >+ : usr1->login_time.tv_sec - usr2->login_time.tv_sec); >+} >+ >+/******************************************************************* >+ Get a list of the names of all users logged into this machine >+ ********************************************************************/ >+ > static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) > { >- char **users = NULL; >- int num_users = 0; >+ char **users; >+ int i, num_users = 0; >+ struct usrinfo *usr_infos = NULL; > struct utmpx *u; > > while ((u = getutxent()) != NULL) { >- char **tmp; >+ struct usrinfo *tmp; > if (u->ut_type != USER_PROCESS) { > continue; > } >- tmp = talloc_realloc(mem_ctx, users, char *, num_users+1); >+ for (i = 0; i < num_users; i++) { >+ /* getutxent can return multiple user entries for the >+ * same user, so ignore any dups */ >+ if (strcmp(u->ut_user, usr_infos[i].name) == 0) { >+ break; >+ } >+ } >+ if (i < num_users) { >+ continue; >+ } >+ >+ tmp = talloc_realloc(mem_ctx, usr_infos, struct usrinfo, >+ num_users+1); > if (tmp == NULL) { >+ TALLOC_FREE(tmp); >+ endutxent(); > return NULL; > } >- users = tmp; >- users[num_users] = talloc_strdup(users, u->ut_user); >- if (users[num_users] == NULL) { >- TALLOC_FREE(users); >+ usr_infos = tmp; >+ usr_infos[num_users].name = talloc_strdup(usr_infos, >+ u->ut_user); >+ if (usr_infos[num_users].name == NULL) { >+ TALLOC_FREE(usr_infos); >+ endutxent(); > return NULL; > } >+ usr_infos[num_users].login_time.tv_sec = u->ut_tv.tv_sec; >+ usr_infos[num_users].login_time.tv_usec = u->ut_tv.tv_usec; > num_users += 1; > } >+ >+ /* Sort the user list by time, oldest first */ >+ if (num_users > 1) { >+ qsort(usr_infos, num_users, sizeof(struct usrinfo), >+ usr_info_cmp); >+ } >+ >+ users = (char**)talloc_array(mem_ctx, char*, num_users); >+ if (users) { >+ for (i = 0; i < num_users; i++) { >+ users[i] = talloc_move(users, &usr_infos[i].name); >+ } >+ } >+ TALLOC_FREE(usr_infos); >+ endutxent(); >+ errno = 0; > return users; > } > >@@ -67,8 +130,129 @@ static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) > > #endif > >+static int dom_user_cmp(const void *p1, const void *p2) >+{ >+ /* Called from qsort to compare two domain users in a dom_usr_t array >+ * for sorting by login time. Return >0 if usr1 login time was later >+ * than usr2 login time, <0 if it was earlier */ >+ const struct dom_usr *usr1 = (const struct dom_usr *)p1; >+ const struct dom_usr *usr2 = (const struct dom_usr *)p2; >+ >+ return (usr1->login_time - usr2->login_time); >+} >+ >+/******************************************************************* >+ Get a list of the names of all users of this machine who are >+ logged into the domain. >+ >+ This should return a list of the users on this machine who are >+ logged into the domain (i.e. have been authenticated by the domain's >+ password server) but that doesn't fit well with the normal Samba >+ scenario where accesses out to the domain are made through smbclient >+ with each such session individually authenticated. So about the best >+ we can do currently is to list sessions of local users connected to >+ this server, which means that to get themself included in the list a >+ local user must create a session to the local samba server by running: >+ smbclient \\\\localhost\\share >+ >+ FIXME: find a better way to get local users logged into the domain >+ in this list. >+ ********************************************************************/ >+ >+static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx) >+{ >+ struct sessionid *session_list = NULL; >+ char *machine_name, *p, *nm; >+ const char *sep; >+ struct dom_usr *users, *tmp; >+ int i, num_users, num_sessions; >+ >+ sep = lp_winbind_separator(); >+ if (!sep) { >+ sep = "\\"; >+ } >+ >+ num_sessions = list_sessions(mem_ctx, &session_list); >+ if (num_sessions == 0) { >+ errno = 0; >+ return NULL; >+ } >+ >+ users = talloc_array(mem_ctx, struct dom_usr, num_sessions); >+ if (users == NULL) { >+ TALLOC_FREE(session_list); >+ return NULL; >+ } >+ >+ for (i=num_users=0; i<num_sessions; i++) { >+ if (!session_list[i].username >+ || !session_list[i].remote_machine) { >+ continue; >+ } >+ p = strpbrk(session_list[i].remote_machine, "./"); >+ if (p) { >+ *p = '\0'; >+ } >+ machine_name = talloc_asprintf_strupper_m( >+ users, "%s", session_list[i].remote_machine); >+ if (machine_name == NULL) { >+ DEBUG(10, ("talloc_asprintf failed\n")); >+ continue; >+ } >+ if (strcmp(machine_name, global_myname()) == 0) { >+ p = session_list[i].username; >+ nm = strstr(p, sep); >+ if (nm) { >+ /* >+ * "domain+name" format so split domain and >+ * name components >+ */ >+ *nm = '\0'; >+ nm += strlen(sep); >+ users[num_users].domain = >+ talloc_asprintf_strupper_m(users, >+ "%s", p); >+ users[num_users].name = talloc_strdup(users, >+ nm); >+ } else { >+ /* >+ * Simple user name so get domain from smb.conf >+ */ >+ users[num_users].domain = >+ talloc_strdup(users, lp_workgroup()); >+ users[num_users].name = talloc_strdup(users, >+ p); >+ } >+ users[num_users].login_time = >+ session_list[i].connect_start; >+ num_users++; >+ } >+ TALLOC_FREE(machine_name); >+ } >+ TALLOC_FREE(session_list); >+ >+ tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users); >+ if (tmp == NULL) { >+ return NULL; >+ } >+ users = tmp; >+ >+ /* Sort the user list by time, oldest first */ >+ if (num_users > 1) { >+ qsort(users, num_users, sizeof(struct dom_usr), dom_user_cmp); >+ } >+ >+ errno = 0; >+ return users; >+} >+ > /******************************************************************* >- Fill in the values for the struct wkssvc_NetWkstaInfo100. >+ RPC Workstation Service request NetWkstaGetInfo with level 100. >+ Returns to the requester: >+ - The machine name. >+ - The smb version number >+ - The domain name. >+ Returns a filled in wkssvc_NetWkstaInfo100 struct. > ********************************************************************/ > > static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx) >@@ -92,6 +276,14 @@ static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx) > return info100; > } > >+/******************************************************************* >+ RPC Workstation Service request NetWkstaGetInfo with level 101. >+ Returns to the requester: >+ - As per NetWkstaGetInfo with level 100, plus: >+ - The LANMAN directory path (not currently supported). >+ Returns a filled in wkssvc_NetWkstaInfo101 struct. >+ ********************************************************************/ >+ > static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx) > { > struct wkssvc_NetWkstaInfo101 *info101; >@@ -109,11 +301,19 @@ static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx) > info101, "%s", global_myname()); > info101->domain_name = talloc_asprintf_strupper_m( > info101, "%s", lp_workgroup()); >- info101->lan_root = NULL; >+ info101->lan_root = ""; > > return info101; > } > >+/******************************************************************* >+ RPC Workstation Service request NetWkstaGetInfo with level 102. >+ Returns to the requester: >+ - As per NetWkstaGetInfo with level 101, plus: >+ - The number of logged in users. >+ Returns a filled in wkssvc_NetWkstaInfo102 struct. >+ ********************************************************************/ >+ > static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx) > { > struct wkssvc_NetWkstaInfo102 *info102; >@@ -132,35 +332,63 @@ static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx) > info102, "%s", global_myname()); > info102->domain_name = talloc_asprintf_strupper_m( > info102, "%s", lp_workgroup()); >- info102->lan_root = NULL; >+ info102->lan_root = ""; > > users = get_logged_on_userlist(talloc_tos()); > info102->logged_on_users = talloc_array_length(users); >+ > TALLOC_FREE(users); > > return info102; > } > > /******************************************************************** >- only supports info level 100 at the moment. >+ Handling for RPC Workstation Service request NetWkstaGetInfo > ********************************************************************/ > > WERROR _wkssvc_NetWkstaGetInfo(pipes_struct *p, struct wkssvc_NetWkstaGetInfo *r) > { > switch (r->in.level) { > case 100: >+ /* Level 100 can be allowed from anyone including anonymous >+ * so no access checks are needed for this case */ > r->out.info->info100 = create_wks_info_100(p->mem_ctx); > if (r->out.info->info100 == NULL) { > return WERR_NOMEM; > } > break; > case 101: >+ /* Level 101 can be allowed from any logged in user */ >+ if (!nt_token_check_sid(&global_sid_Authenticated_Users, >+ p->server_info->ptok)) { >+ DEBUG(1,("User not allowed for NetWkstaGetInfo level " >+ "101\n")); >+ DEBUGADD(3,(" - does not have sid for Authenticated " >+ "Users %s:\n", >+ sid_string_dbg( >+ &global_sid_Authenticated_Users))); >+ debug_nt_user_token(DBGC_CLASS, 3, >+ p->server_info->ptok); >+ return WERR_ACCESS_DENIED; >+ } > r->out.info->info101 = create_wks_info_101(p->mem_ctx); > if (r->out.info->info101 == NULL) { > return WERR_NOMEM; > } > break; > case 102: >+ /* Level 102 Should only be allowed from a domain administrator */ >+ if (!nt_token_check_sid(&global_sid_Builtin_Administrators, >+ p->server_info->ptok)) { >+ DEBUG(1,("User not allowed for NetWkstaGetInfo level " >+ "102\n")); >+ DEBUGADD(3,(" - does not have sid for Administrators " >+ "group %s, sids are:\n", >+ sid_string_dbg(&global_sid_Builtin_Administrators))); >+ debug_nt_user_token(DBGC_CLASS, 3, >+ p->server_info->ptok); >+ return WERR_ACCESS_DENIED; >+ } > r->out.info->info102 = create_wks_info_102(p->mem_ctx); > if (r->out.info->info102 == NULL) { > return WERR_NOMEM; >@@ -183,6 +411,13 @@ WERROR _wkssvc_NetWkstaSetInfo(pipes_struct *p, struct wkssvc_NetWkstaSetInfo *r > return WERR_NOT_SUPPORTED; > } > >+/******************************************************************** >+ RPC Workstation Service request NetWkstaEnumUsers with level 0: >+ Returns to the requester: >+ - the user names of the logged in users. >+ Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct. >+ ********************************************************************/ >+ > static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( > TALLOC_CTX *mem_ctx) > { >@@ -196,12 +431,14 @@ static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( > } > > users = get_logged_on_userlist(talloc_tos()); >- if (users == NULL) { >+ if (users == NULL && errno != 0) { >+ DEBUG(1,("get_logged_on_userlist error %d: %s\n", >+ errno, strerror(errno))); > TALLOC_FREE(ctr0); > return NULL; > } > >- num_users = talloc_array_length(users); >+ num_users = (users) ? talloc_array_length(users) : 0; > ctr0->entries_read = num_users; > ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0, > num_users); >@@ -219,21 +456,143 @@ static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( > } > > /******************************************************************** >+ RPC Workstation Service request NetWkstaEnumUsers with level 1. >+ Returns to the requester: >+ - the user names of the logged in users, >+ - the domain or machine each is logged into, >+ - the password server that was used to authenticate each, >+ - other domains each user is logged into (not currently supported). >+ Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct. >+ ********************************************************************/ >+ >+static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1( >+ TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1; >+ char **users; >+ struct dom_usr *dom_users; >+ char *pwd_server; >+ int i, j, num_users, num_dom_users; >+ >+ ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1); >+ if (ctr1 == NULL) { >+ return NULL; >+ } >+ >+ users = get_logged_on_userlist(talloc_tos()); >+ if (users == NULL && errno != 0) { >+ DEBUG(1,("get_logged_on_userlist error %d: %s\n", >+ errno, strerror(errno))); >+ TALLOC_FREE(ctr1); >+ return NULL; >+ } >+ num_users = (users) ? talloc_array_length(users) : 0; >+ >+ dom_users = get_domain_userlist(talloc_tos()); >+ if (dom_users == NULL && errno != 0) { >+ TALLOC_FREE(ctr1); >+ TALLOC_FREE(users); >+ return NULL; >+ } >+ num_dom_users = (dom_users) ? talloc_array_length(dom_users) : 0; >+ >+ ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1, >+ num_users+num_dom_users); >+ if (ctr1->user1 == NULL) { >+ TALLOC_FREE(ctr1); >+ TALLOC_FREE(users); >+ TALLOC_FREE(dom_users); >+ return NULL; >+ } >+ >+ if ((pwd_server = talloc_strdup(ctr1->user1, lp_passwordserver()))) { >+ /* The configured password server is a full DNS name but >+ * for the logon server we need to return just the first >+ * component (machine name) of it in upper-case */ >+ char *p = strchr(pwd_server, '.'); >+ if (p) { >+ *p = '\0'; >+ } else { >+ p = pwd_server + strlen(pwd_server); >+ } >+ while (--p >= pwd_server) { >+ *p = toupper(*p); >+ } >+ } else { >+ pwd_server = ""; >+ } >+ >+ >+ /* Put in local users first */ >+ for (i=0; i<num_users; i++) { >+ ctr1->user1[i].user_name = talloc_move(ctr1->user1, &users[i]); >+ >+ /* For a local user the domain name and logon server are >+ * both returned as the local machine's NetBIOS name */ >+ ctr1->user1[i].logon_domain = ctr1->user1[i].logon_server = >+ talloc_asprintf_strupper_m(ctr1->user1, "%s", global_myname()); >+ >+ ctr1->user1[i].other_domains = NULL; /* Maybe in future? */ >+ } >+ >+ /* Now domain users */ >+ for (j=0; j<num_dom_users; j++) { >+ ctr1->user1[i].user_name = >+ talloc_strdup(ctr1->user1, dom_users[j].name); >+ ctr1->user1[i].logon_domain = >+ talloc_strdup(ctr1->user1, dom_users[j].domain); >+ ctr1->user1[i].logon_server = pwd_server; >+ >+ ctr1->user1[i++].other_domains = NULL; /* Maybe in future? */ >+ } >+ >+ ctr1->entries_read = i; >+ >+ TALLOC_FREE(users); >+ TALLOC_FREE(dom_users); >+ return ctr1; >+} >+ >+/******************************************************************** >+ Handling for RPC Workstation Service request NetWkstaEnumUsers >+ (a.k.a Windows NetWkstaUserEnum) > ********************************************************************/ > > WERROR _wkssvc_NetWkstaEnumUsers(pipes_struct *p, struct wkssvc_NetWkstaEnumUsers *r) > { >- if (r->in.info->level != 0) { >- return WERR_UNKNOWN_LEVEL; >+ /* This with any level should only be allowed from a domain administrator */ >+ if (!nt_token_check_sid(&global_sid_Builtin_Administrators, >+ p->server_info->ptok)) { >+ DEBUG(1,("User not allowed for NetWkstaEnumUsers\n")); >+ DEBUGADD(3,(" - does not have sid for Administrators group " >+ "%s\n", sid_string_dbg( >+ &global_sid_Builtin_Administrators))); >+ debug_nt_user_token(DBGC_CLASS, 3, p->server_info->ptok); >+ return WERR_ACCESS_DENIED; > } > >- r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx); >- if (r->out.info->ctr.user0 == NULL) { >- return WERR_NOMEM; >+ switch (r->in.info->level) { >+ case 0: >+ r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx); >+ if (r->out.info->ctr.user0 == NULL) { >+ return WERR_NOMEM; >+ } >+ r->out.info->level = r->in.info->level; >+ *r->out.entries_read = r->out.info->ctr.user0->entries_read; >+ *r->out.resume_handle = 0; >+ break; >+ case 1: >+ r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx); >+ if (r->out.info->ctr.user1 == NULL) { >+ return WERR_NOMEM; >+ } >+ r->out.info->level = r->in.info->level; >+ *r->out.entries_read = r->out.info->ctr.user1->entries_read; >+ *r->out.resume_handle = 0; >+ break; >+ default: >+ return WERR_UNKNOWN_LEVEL; > } >- r->out.info->level = r->in.info->level; >- *r->out.entries_read = r->out.info->ctr.user0->entries_read; >- *r->out.resume_handle = 0; > > return WERR_OK; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6592
:
4486
|
4487
|
4488
|
4489
|
4490
|
4492
|
4496
|
4502
|
4503
|
4524
|
4525
|
4549
|
4555
|
4564
|
4569
|
4906
|
4963
|
4967
| 4989 |
4997
|
5002