The Samba-Bugzilla – Attachment 4564 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]
Updated (and hopefully complete) patch
smb.patch (text/plain), 16.44 KB, created by
Ian Puleston
on 2009-08-14 18:54:32 UTC
(
hide
)
Description:
Updated (and hopefully complete) patch
Filename:
MIME Type:
Creator:
Ian Puleston
Created:
2009-08-14 18:54:32 UTC
Size:
16.44 KB
patch
obsolete
>From 6ca83b9d015479ccddc45598974da2045bea3033 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 3 Aug 2009 16:52:01 +0200 >Subject: [PATCH] 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 7cfd3fb..068f9cd 100644 >--- a/source3/configure.in >+++ b/source3/configure.in >@@ -2016,7 +2016,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 -u a/source3/include/config.h.in b/source3/include/config.h.in >>smb.patch >--- a/source3/include/config.h.in 2008-09-18 04:58:36.000000000 -0700 >+++ b/source3/include/config.h.in 2009-08-06 13:42:20.000000000 -0700 >@@ -676,6 +676,9 @@ > /* Define to 1 if you have the `getutmpx' function. */ > #undef HAVE_GETUTMPX > >+/* Define to 1 if you have the `getutxent' function. */ >+#undef HAVE_GETUTXENT >+ > /* Define to 1 if you have the `getxattr' function. */ > #undef HAVE_GETXATTR > > >diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c >index b06818e..0f889db 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 51256d7f8fdea4e00c92af268328b5bbf2a965a5 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 3 Aug 2009 17:27:11 +0200 >Subject: [PATCH] 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 0f889db..b1deceb 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.0.1 > >diff -u a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c >--- a/source3/rpc_server/srv_wkssvc_nt.c 2009-08-14 16:34:40.000000000 -0700 >+++ b/source3/rpc_server/srv_wkssvc_nt.c 2009-08-14 16:32:01.000000000 -0700 >@@ -35,26 +35,70 @@ > static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx) > { > char **users = NULL; >+ struct timeval *login_times = NULL; > int num_users = 0; >+ int i; >+ bool reordered; > struct utmpx *u; > > while ((u = getutxent()) != NULL) { > char **tmp; >+ struct timeval *tmp2; > if (u->ut_type != USER_PROCESS) { > continue; > } >+ 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, users[i]) == 0) break; >+ } >+ if (i < num_users) { >+ continue; >+ } >+ > tmp = talloc_realloc(mem_ctx, users, char *, num_users+1); >- if (tmp == NULL) { >+ tmp2 = talloc_realloc(mem_ctx, login_times, struct timeval, num_users+1); >+ if (tmp == NULL || tmp2 == NULL) { >+ TALLOC_FREE(tmp); >+ TALLOC_FREE(tmp2); >+ endutent(); > return NULL; > } > users = tmp; >+ login_times = tmp2; > users[num_users] = talloc_strdup(users, u->ut_user); > if (users[num_users] == NULL) { > TALLOC_FREE(users); >+ TALLOC_FREE(login_times); >+ endutent(); > return NULL; > } >+ login_times[num_users].tv_sec = u->ut_tv.tv_sec; >+ login_times[num_users].tv_usec = u->ut_tv.tv_usec; > num_users += 1; > } >+ >+ /* Sort the user list by time, oldest first */ >+ do { >+ reordered = False; >+ for (i = 0; i < num_users-1; i++) { >+ if (login_times[i].tv_sec > login_times[i+1].tv_sec >+ || (login_times[i].tv_sec == login_times[i+1].tv_sec >+ && login_times[i].tv_usec > login_times[i+1].tv_usec)) { >+ char *tmp1 = users[i]; >+ struct timeval tmp2 = login_times[i]; >+ users[i] = users[i+1]; >+ users[i+1] = tmp1; >+ login_times[i] = login_times[i+1]; >+ login_times[i+1] = tmp2; >+ reordered = True; >+ } >+ } >+ } while (reordered); >+ >+ TALLOC_FREE(login_times); >+ endutent(); >+ errno = 0; > return users; > } > >@@ -136,6 +180,7 @@ > > users = get_logged_on_userlist(talloc_tos()); > info102->logged_on_users = talloc_array_length(users); >+ > TALLOC_FREE(users); > > return info102; >@@ -183,6 +228,9 @@ > return WERR_NOT_SUPPORTED; > } > >+/******************************************************************** >+ ********************************************************************/ >+ > static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( > TALLOC_CTX *mem_ctx) > { >@@ -196,12 +244,14 @@ > } > > 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); >@@ -221,20 +271,151 @@ > /******************************************************************** > ********************************************************************/ > >+static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1( >+ TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1; >+ char **users; >+ char *pwd_server, *machine_name, *p, *nm; >+ const char *sep; >+ int i, j, num_users, num_sessions; >+ struct sessionid *session_list; >+ >+ 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; >+ >+ session_list = NULL; >+ num_sessions = list_sessions(mem_ctx, &session_list); >+ >+ ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1, >+ num_users+num_sessions); >+ if (ctr1->user1 == NULL) { >+ TALLOC_FREE(ctr1); >+ TALLOC_FREE(users); >+ TALLOC_FREE(session_list); >+ return NULL; >+ } >+ >+ if ((pwd_server = lp_passwordserver())) { >+ /* The configured password server is a full DNS name but >+ * for the logon server we want to return just the first >+ * component (machine name) of it in upper-case */ >+ int len = 0; >+ while (pwd_server[len] != '.') len++; >+ if (len == 0) len = strlen(pwd_server); >+ pwd_server = talloc_strndup(ctr1->user1, pwd_server, len); >+ if (pwd_server) { >+ while (--len >= 0) pwd_server[len] = toupper(pwd_server[len]); >+ } >+ } >+ >+ sep = lp_winbind_separator(); >+ if (!sep) sep = "\\"; >+ >+ /* 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. This should be 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 Samba scenario where >+ * accesses out to the domain are made through smbclient. 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. */ >+ for (j=0; j<num_sessions; j++) { >+ DEBUG(3,("Found session for %s host %s machine %s\n", >+ session_list[j].username, >+ session_list[j].hostname, >+ session_list[j].remote_machine)); >+ if (!session_list[j].username || !session_list[j].remote_machine) { >+ continue; >+ } >+ p = strpbrk(session_list[j].remote_machine, "./"); >+ if (p) *p = '\0'; >+ machine_name = talloc_asprintf_strupper_m(ctr1->user1, "%s", >+ session_list[j].remote_machine); >+ if (machine_name && strcmp(machine_name, global_myname()) == 0) >+ { >+ p = session_list[j].username; >+ nm = strstr(p, sep); >+ if (nm) { >+ *nm = '\0'; /* Split domain and name components */ >+ nm += strlen(sep); >+ ctr1->user1[i].logon_domain = >+ talloc_asprintf_strupper_m(ctr1->user1, "%s", p); >+ ctr1->user1[i].user_name = talloc_strdup(ctr1->user1, nm); >+ } else { >+ /* Simple user name so assume domain from smb.conf */ >+ ctr1->user1[i].logon_domain = >+ talloc_strdup(ctr1->user1, lp_workgroup()); >+ ctr1->user1[i].user_name = talloc_strdup(ctr1->user1, p); >+ } >+ ctr1->user1[i].logon_server = pwd_server; >+ >+ ctr1->user1[i++].other_domains = NULL; /* Maybe in future? */ >+ } >+ TALLOC_FREE(machine_name); >+ } >+ >+ ctr1->entries_read = i; >+ >+ TALLOC_FREE(users); >+ TALLOC_FREE(session_list); >+ return ctr1; >+} >+ >+/******************************************************************** >+ ********************************************************************/ >+ > WERROR _wkssvc_NetWkstaEnumUsers(pipes_struct *p, struct wkssvc_NetWkstaEnumUsers *r) > { >- if (r->in.info->level != 0) { >+ 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->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; > } >
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