The Samba-Bugzilla – Attachment 4569 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 patch
smb.patch (text/plain), 19.19 KB, created by
Ian Puleston
on 2009-08-18 15:59:10 UTC
(
hide
)
Description:
Updated patch
Filename:
MIME Type:
Creator:
Ian Puleston
Created:
2009-08-18 15:59:10 UTC
Size:
19.19 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-15 19:29:48.000000000 -0700 >+++ b/source3/rpc_server/srv_wkssvc_nt.c 2009-08-15 19:29:10.000000000 -0700 >@@ -28,33 +28,93 @@ > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_RPC_SRV > >+typedef struct { >+ char *name; >+ char *domain; >+ time_t login_time; >+} dom_usr_t; >+ > #ifdef HAVE_GETUTXENT > > #include <utmpx.h> > >+typedef struct { >+ char *name; >+ struct timeval login_time; >+} usrinfo_t; >+ >+static int usr_info_cmp(const void *p1, const void *p2) >+{ >+ const usrinfo_t *usr1 = p1; >+ const usrinfo_t *usr2 = 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; >+ usrinfo_t *usr_infos = NULL; > struct utmpx *u; > > while ((u = getutxent()) != NULL) { >- char **tmp; >+ usrinfo_t *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, usrinfo_t, num_users+1); > if (tmp == NULL) { >+ TALLOC_FREE(tmp); >+ endutent(); > 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); >+ endutent(); > 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(usrinfo_t), 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); >+ endutent(); >+ errno = 0; > return users; > } > >@@ -67,6 +127,111 @@ > > #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 dom_usr_t *usr1 = p1; >+ const dom_usr_t *usr2 = 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 dom_usr_t *get_domain_userlist(TALLOC_CTX *mem_ctx) >+{ >+ struct sessionid *session_list = NULL; >+ char *machine_name, *p, *nm; >+ const char *sep; >+ dom_usr_t *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, dom_usr_t, 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 && 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; >+ DEBUG(3,("User %s time %d !!!!\n", >+ users[num_users].name, users[num_users].login_time)); >+ num_users++; >+ } >+ TALLOC_FREE(machine_name); >+ } >+ TALLOC_FREE(session_list); >+ >+ tmp = talloc_realloc(mem_ctx, users, dom_usr_t, 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(dom_usr_t), dom_user_cmp); >+ } >+ >+ errno = 0; >+ return users; >+} >+ > /******************************************************************* > Fill in the values for the struct wkssvc_NetWkstaInfo100. > ********************************************************************/ >@@ -136,6 +301,7 @@ > > users = get_logged_on_userlist(talloc_tos()); > info102->logged_on_users = talloc_array_length(users); >+ > TALLOC_FREE(users); > > return info102; >@@ -183,6 +349,9 @@ > return WERR_NOT_SUPPORTED; > } > >+/******************************************************************** >+ ********************************************************************/ >+ > static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0( > TALLOC_CTX *mem_ctx) > { >@@ -196,12 +365,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 +392,119 @@ > /******************************************************************** > ********************************************************************/ > >+static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1( >+ TALLOC_CTX *mem_ctx) >+{ >+ struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1; >+ char **users; >+ dom_usr_t *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 = 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]); >+ } >+ } >+ >+ /* 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; >+} >+ >+/******************************************************************** >+ ********************************************************************/ >+ > 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