summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbind_nss_irix.c
diff options
context:
space:
mode:
authorJames Peach <jpeach@samba.org>2006-05-04 00:45:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:16:43 -0500
commitd2418fbf276121eae08f05cbf3d6b3c84eb09887 (patch)
tree6008f684cf24707edfc36816b2e4ef5819b7e5f5 /source3/nsswitch/winbind_nss_irix.c
parent4ab90ea08c9337128a75a34662c27a3d6bf88d32 (diff)
downloadsamba-d2418fbf276121eae08f05cbf3d6b3c84eb09887.tar.gz
samba-d2418fbf276121eae08f05cbf3d6b3c84eb09887.tar.bz2
samba-d2418fbf276121eae08f05cbf3d6b3c84eb09887.zip
r15425: Use dynamic buffers in the IRIX nsswithch module to prevent truncation
of long group lists. (This used to be commit d348d796c16679297e1f0304b8b2ba0f42010733)
Diffstat (limited to 'source3/nsswitch/winbind_nss_irix.c')
-rw-r--r--source3/nsswitch/winbind_nss_irix.c260
1 files changed, 182 insertions, 78 deletions
diff --git a/source3/nsswitch/winbind_nss_irix.c b/source3/nsswitch/winbind_nss_irix.c
index 05085ba1f3..2fbf3e0df8 100644
--- a/source3/nsswitch/winbind_nss_irix.c
+++ b/source3/nsswitch/winbind_nss_irix.c
@@ -4,6 +4,7 @@
Windows NT Domain nsswitch module
Copyright (C) Tim Potter 2000
+ Copyright (C) James Peach 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -23,8 +24,19 @@
#include "winbind_client.h"
+#ifndef PRINTF_ATTRIBUTE
+#define PRINTF_ATTRIBUTE(m, n)
+#endif
+
+#ifndef HAVE_ASPRINTF_DECL
+/*PRINTFLIKE2 */
+int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3);
+#endif
+
#ifdef HAVE_NS_API_H
#undef VOLATILE
+#undef STATIC
+#undef DYNAMIC
#include <ns_daemon.h>
#endif
@@ -165,13 +177,10 @@ static int
winbind_callback(nsd_file_t **rqp, int fd)
{
struct winbindd_response response;
- struct winbindd_pw *pw = &response.data.pw;
- struct winbindd_gr *gr = &response.data.gr;
nsd_file_t *rq;
NSS_STATUS status;
- fstring result;
- char *members;
- int i, maxlen;
+ char * result = NULL;
+ size_t rlen;
dequeue_request();
@@ -192,76 +201,164 @@ winbind_callback(nsd_file_t **rqp, int fd)
nsd_logprintf(NSD_LOG_MIN,
"callback (winbind) returning not found, status = %d\n",
status);
- rq->f_status = NS_NOTFOUND;
+
+ switch (status) {
+ case NSS_STATUS_UNAVAIL:
+ rq->f_status = NS_UNAVAIL;
+ break;
+ case NSS_STATUS_TRYAGAIN:
+ rq->f_status = NS_TRYAGAIN;
+ break;
+ case NSS_STATUS_NOTFOUND:
+ /* FALLTHRU */
+ default:
+ rq->f_status = NS_NOTFOUND;
+ }
+
return NSD_NEXT;
}
- maxlen = sizeof(result) - 1;
-
switch ((int)rq->f_cmd_data) {
case WINBINDD_WINS_BYNAME:
case WINBINDD_WINS_BYIP:
- snprintf(result,maxlen,"%s\n",response.data.winsresp);
- break;
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) WINS_BYNAME | WINS_BYIP\n");
+
+ rlen = asprintf(&result, "%s\n", response.data.winsresp);
+ if (rlen == 0 || result == NULL) {
+ return NSD_ERROR;
+ }
+
+ free_response(&response);
+
+ nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
+ nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
+ return NSD_OK;
+
case WINBINDD_GETPWUID:
case WINBINDD_GETPWNAM:
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- break;
+ {
+ struct winbindd_pw *pw = &response.data.pw;
+
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) GETPWUID | GETPWUID\n");
+
+ rlen = asprintf(&result,"%s:%s:%d:%d:%s:%s:%s\n",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+ if (rlen == 0 || result == NULL)
+ return NSD_ERROR;
+
+ free_response(&response);
+
+ nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
+ nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
+ return NSD_OK;
+ }
+
case WINBINDD_GETGRNAM:
case WINBINDD_GETGRGID:
- if (gr->num_gr_mem && response.extra_data.data)
- members = response.extra_data.data;
- else
- members = "";
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
- break;
+ {
+ const struct winbindd_gr *gr = &response.data.gr;
+ const char * members;
+
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) GETGRNAM | GETGRGID\n");
+
+ if (gr->num_gr_mem && response.extra_data.data) {
+ members = response.extra_data.data;
+ } else {
+ members = "";
+ }
+
+ rlen = asprintf(&result, "%s:%s:%d:%s\n",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
+ if (rlen == 0 || result == NULL)
+ return NSD_ERROR;
+
+ free_response(&response);
+
+ nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
+ nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
+ return NSD_OK;
+ }
+
case WINBINDD_SETGRENT:
case WINBINDD_SETPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n");
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) SETGRENT | SETPWENT\n");
free_response(&response);
return(do_list(1,rq));
+
case WINBINDD_GETGRENT:
case WINBINDD_GETGRLST:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETGRENT responses\n",
- response.data.num_entries);
- if (response.data.num_entries) {
- gr = (struct winbindd_gr *)response.extra_data.data;
- if (! gr ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data.data\n");
- free_response(&response);
- return NSD_ERROR;
- }
- members = (char *)response.extra_data.data +
- (response.data.num_entries * sizeof(struct winbindd_gr));
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid,
- &members[gr->gr_mem_ofs]);
- nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
- gr++;
- }
- }
- i = response.data.num_entries;
- free_response(&response);
- if (i < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
+ {
+ int entries;
+
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) GETGRENT | GETGRLIST %d responses\n",
+ response.data.num_entries);
+
+ if (response.data.num_entries) {
+ const struct winbindd_gr *gr = &response.data.gr;
+ const char * members;
+ fstring grp_name;
+ int i;
+
+ gr = (struct winbindd_gr *)response.extra_data.data;
+ if (! gr ) {
+ nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
+ free_response(&response);
+ return NSD_ERROR;
+ }
+
+ members = (char *)response.extra_data.data +
+ (response.data.num_entries * sizeof(struct winbindd_gr));
+
+ for (i = 0; i < response.data.num_entries; i++) {
+ snprintf(grp_name, sizeof(grp_name) - 1, "%s:%s:%d:",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid);
+
+ nsd_append_element(rq, NS_SUCCESS, result, rlen);
+ nsd_append_result(rq, NS_SUCCESS,
+ &members[gr->gr_mem_ofs],
+ strlen(&members[gr->gr_mem_ofs]));
+
+ /* Don't log the whole list, because it might be
+ * _really_ long and we probably don't want to clobber
+ * the log with it.
+ */
+ nsd_logprintf(NSD_LOG_MIN, " %s (...)\n", grp_name);
+
+ gr++;
+ }
+ }
+
+ entries = response.data.num_entries;
+ free_response(&response);
+ if (entries < MAX_GETPWENT_USERS)
+ return(do_list(2,rq));
+ else
+ return(do_list(1,rq));
+ }
+
case WINBINDD_GETPWENT:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETPWENT responses\n",
+ {
+ int entries;
+
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) GETPWENT %d responses\n",
response.data.num_entries);
+
if (response.data.num_entries) {
+ struct winbindd_pw *pw = &response.data.pw;
+ int i;
+
pw = (struct winbindd_pw *)response.extra_data.data;
if (! pw ) {
nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
@@ -269,41 +366,46 @@ winbind_callback(nsd_file_t **rqp, int fd)
return NSD_ERROR;
}
for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
+ result = NULL;
+ rlen = asprintf(&result, "%s:%s:%d:%d:%s:%s:%s",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+
+ if (rlen != 0 && result != NULL) {
+ nsd_logprintf(NSD_LOG_MIN, " %s\n",result);
+ nsd_append_element(rq, NS_SUCCESS, result, rlen);
+ free(result);
+ }
+
pw++;
}
}
- i = response.data.num_entries;
+
+ entries = response.data.num_entries;
free_response(&response);
- if (i < MAX_GETPWENT_USERS)
+ if (entries < MAX_GETPWENT_USERS)
return(do_list(2,rq));
else
return(do_list(1,rq));
+ }
+
case WINBINDD_ENDGRENT:
case WINBINDD_ENDPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n");
- nsd_append_element(rq,NS_SUCCESS,"\n",1);
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) ENDGRENT | ENDPWENT\n");
+ nsd_append_element(rq, NS_SUCCESS, "\n", 1);
free_response(&response);
return NSD_NEXT;
+
default:
free_response(&response);
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n");
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) invalid command %d\n", (int)rq->f_cmd_data);
return NSD_NEXT;
}
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result);
- /* free any extra data area in response structure */
- free_response(&response);
- nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE);
- return NSD_OK;
}
static int
@@ -349,14 +451,16 @@ send_next_request(nsd_file_t *rq, struct winbindd_request *request)
return NSD_NEXT;
}
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n",
+ nsd_logprintf(NSD_LOG_MIN,
+ "send_next_request (winbind) %d, timeout = %d sec\n",
rq->f_cmd_data, timeout);
status = winbindd_send_request((int)rq->f_cmd_data,request);
SAFE_FREE(request);
if (status != NSS_STATUS_SUCCESS) {
nsd_logprintf(NSD_LOG_MIN,
- "send_next_request (winbind) error status = %d\n",status);
+ "send_next_request (winbind) error status = %d\n",
+ status);
rq->f_status = status;
return NSD_NEXT;
}