?? irpmarshall.c
字號:
/* * Copyright(c) 1989, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#if defined(LIBC_SCCS) && !defined(lint)static const char rcsid[] = "$Id: irpmarshall.c,v 1.3.206.3 2004/03/17 01:13:34 marka Exp $";#endif /* LIBC_SCCS and not lint */#if 0Check values are in approrpriate endian order.Double check memory allocations on unmarhsalling#endif/* Extern */#include "port_before.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <stdio.h>#include <ctype.h>#include <pwd.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <utmp.h>#include <unistd.h>#include <assert.h>#include <errno.h>#include <irs.h>#include <isc/memcluster.h>#include <isc/irpmarshall.h>#include "port_after.h"#ifndef HAVE_STRNDUPstatic char *strndup(const char *str, size_t len);#endifstatic char **splitarray(const char *buffer, const char *buffend, char delim);static int joinarray(char * const * argv, char *buffer, char delim);static char *getfield(char **res, size_t reslen, char **buffer, char delim);static size_t joinlength(char * const *argv);static void free_array(char **argv, size_t entries);#define ADDR_T_STR(x) (x == AF_INET ? "AF_INET" :\ (x == AF_INET6 ? "AF_INET6" : "UNKNOWN"))#define MAXPADDRSIZE (sizeof "255.255.255.255" + 1)static char COMMA = ',';static const char *COMMASTR = ",";static const char *COLONSTR = ":";/* See big comment at bottom of irpmarshall.h for description. */#ifdef WANT_IRS_PW/* +++++++++++++++++++++++++ struct passwd +++++++++++++++++++++++++ *//* * int irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) * * notes: * * See above * * return: * * 0 on sucess, -1 on failure. * */intirp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) { size_t need = 1 ; /* for null byte */ char pwUid[24]; char pwGid[24]; char pwChange[24]; char pwExpire[24]; const char *pwClass; const char *fieldsep = COLONSTR; if (pw == NULL || len == NULL) { errno = EINVAL; return (-1); } sprintf(pwUid, "%ld", (long)pw->pw_uid); sprintf(pwGid, "%ld", (long)pw->pw_gid);#ifdef HAVE_PW_CHANGE sprintf(pwChange, "%ld", (long)pw->pw_change);#else pwChange[0] = '0'; pwChange[1] = '\0';#endif#ifdef HAVE_PW_EXPIRE sprintf(pwExpire, "%ld", (long)pw->pw_expire);#else pwExpire[0] = '0'; pwExpire[1] = '\0';#endif#ifdef HAVE_PW_CLASS pwClass = pw->pw_class;#else pwClass = "";#endif need += strlen(pw->pw_name) + 1; /* one for fieldsep */ need += strlen(pw->pw_passwd) + 1; need += strlen(pwUid) + 1; need += strlen(pwGid) + 1; need += strlen(pwClass) + 1; need += strlen(pwChange) + 1; need += strlen(pwExpire) + 1; need += strlen(pw->pw_gecos) + 1; need += strlen(pw->pw_dir) + 1; need += strlen(pw->pw_shell) + 1; if (buffer == NULL) { *len = need; return (0); } if (*buffer != NULL && need > *len) { errno = EINVAL; return (-1); } if (*buffer == NULL) { need += 2; /* for CRLF */ *buffer = memget(need); if (*buffer == NULL) { errno = ENOMEM; return (-1); } *len = need; } strcpy(*buffer, pw->pw_name); strcat(*buffer, fieldsep); strcat(*buffer, pw->pw_passwd); strcat(*buffer, fieldsep); strcat(*buffer, pwUid); strcat(*buffer, fieldsep); strcat(*buffer, pwGid); strcat(*buffer, fieldsep); strcat(*buffer, pwClass); strcat(*buffer, fieldsep); strcat(*buffer, pwChange); strcat(*buffer, fieldsep); strcat(*buffer, pwExpire); strcat(*buffer, fieldsep); strcat(*buffer, pw->pw_gecos); strcat(*buffer, fieldsep); strcat(*buffer, pw->pw_dir); strcat(*buffer, fieldsep); strcat(*buffer, pw->pw_shell); strcat(*buffer, fieldsep); return (0);}/* * int irp_unmarshall_pw(struct passwd *pw, char *buffer) * * notes: * * see above * * return: * * 0 on success, -1 on failure * */intirp_unmarshall_pw(struct passwd *pw, char *buffer) { char *name, *pass, *class, *gecos, *dir, *shell; uid_t pwuid; gid_t pwgid; time_t pwchange; time_t pwexpire; char *p; long t; char tmpbuf[24]; char *tb = &tmpbuf[0]; char fieldsep = ':'; int myerrno = EINVAL; name = pass = class = gecos = dir = shell = NULL; p = buffer; /* pw_name field */ name = NULL; if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0) { goto error; } /* pw_passwd field */ pass = NULL; if (getfield(&pass, 0, &p, fieldsep) == NULL) { /* field can be empty */ goto error; } /* pw_uid field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } pwuid = (uid_t)t; if ((long) pwuid != t) { /* value must have been too big. */ goto error; } /* pw_gid field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } pwgid = (gid_t)t; if ((long)pwgid != t) { /* value must have been too big. */ goto error; } /* pw_class field */ class = NULL; if (getfield(&class, 0, &p, fieldsep) == NULL) { goto error; } /* pw_change field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } pwchange = (time_t)t; if ((long)pwchange != t) { /* value must have been too big. */ goto error; } /* pw_expire field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } pwexpire = (time_t)t; if ((long) pwexpire != t) { /* value must have been too big. */ goto error; } /* pw_gecos field */ gecos = NULL; if (getfield(&gecos, 0, &p, fieldsep) == NULL) { goto error; } /* pw_dir field */ dir = NULL; if (getfield(&dir, 0, &p, fieldsep) == NULL) { goto error; } /* pw_shell field */ shell = NULL; if (getfield(&shell, 0, &p, fieldsep) == NULL) { goto error; } pw->pw_name = name; pw->pw_passwd = pass; pw->pw_uid = pwuid; pw->pw_gid = pwgid; pw->pw_gecos = gecos; pw->pw_dir = dir; pw->pw_shell = shell;#ifdef HAVE_PW_CHANGE pw->pw_change = pwchange;#endif#ifdef HAVE_PW_CLASS pw->pw_class = class;#endif#ifdef HAVE_PW_EXPIRE pw->pw_expire = pwexpire;#endif return (0); error: errno = myerrno; if (name != NULL) free(name); if (pass != NULL) free(pass); if (gecos != NULL) free(gecos); if (dir != NULL) free(dir); if (shell != NULL) free(shell); return (-1);}/* ------------------------- struct passwd ------------------------- */#endif /* WANT_IRS_PW *//* +++++++++++++++++++++++++ struct group +++++++++++++++++++++++++ *//* * int irp_marshall_gr(const struct group *gr, char **buffer, size_t *len) * * notes: * * see above. * * return: * * 0 on success, -1 on failure */intirp_marshall_gr(const struct group *gr, char **buffer, size_t *len) { size_t need = 1; /* for null byte */ char grGid[24]; const char *fieldsep = COLONSTR; if (gr == NULL || len == NULL) { errno = EINVAL; return (-1); } sprintf(grGid, "%ld", (long)gr->gr_gid); need += strlen(gr->gr_name) + 1;#ifndef MISSING_GR_PASSWD need += strlen(gr->gr_passwd) + 1;#else need++;#endif need += strlen(grGid) + 1; need += joinlength(gr->gr_mem) + 1; if (buffer == NULL) { *len = need; return (0); } if (*buffer != NULL && need > *len) { errno = EINVAL; return (-1); } if (*buffer == NULL) { need += 2; /* for CRLF */ *buffer = memget(need); if (*buffer == NULL) { errno = ENOMEM; return (-1); } *len = need; } strcpy(*buffer, gr->gr_name); strcat(*buffer, fieldsep);#ifndef MISSING_GR_PASSWD strcat(*buffer, gr->gr_passwd);#endif strcat(*buffer, fieldsep); strcat(*buffer, grGid); strcat(*buffer, fieldsep); joinarray(gr->gr_mem, *buffer, COMMA) ; strcat(*buffer, fieldsep); return (0);}/* * int irp_unmarshall_gr(struct group *gr, char *buffer) * * notes: * * see above * * return: * * 0 on success and -1 on failure. * */intirp_unmarshall_gr(struct group *gr, char *buffer) { char *p, *q; gid_t grgid; long t; char *name = NULL; char *pass = NULL; char **members = NULL; char tmpbuf[24]; char *tb; char fieldsep = ':'; int myerrno = EINVAL; if (gr == NULL || buffer == NULL) { errno = EINVAL; return (-1); } p = buffer; /* gr_name field */ name = NULL; if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) { goto error; } /* gr_passwd field */ pass = NULL; if (getfield(&pass, 0, &p, fieldsep) == NULL) { goto error; } /* gr_gid field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0U) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } grgid = (gid_t)t; if ((long) grgid != t) { /* value must have been too big. */ goto error; } /* gr_mem field. Member names are separated by commas */ q = strchr(p, fieldsep); if (q == NULL) { goto error; } members = splitarray(p, q, COMMA); if (members == NULL) { myerrno = errno; goto error; } p = q + 1; gr->gr_name = name;#ifndef MISSING_GR_PASSWD gr->gr_passwd = pass;#endif gr->gr_gid = grgid; gr->gr_mem = members; return (0); error: errno = myerrno; if (name != NULL) free(name); if (pass != NULL) free(pass); return (-1);}/* ------------------------- struct group ------------------------- *//* +++++++++++++++++++++++++ struct servent +++++++++++++++++++++++++ *//* * int irp_marshall_sv(const struct servent *sv, char **buffer, size_t *len) * * notes: * * see above * * return: * * 0 on success, -1 on failure. * */intirp_marshall_sv(const struct servent *sv, char **buffer, size_t *len) { size_t need = 1; /* for null byte */ char svPort[24]; const char *fieldsep = COLONSTR; short realport; if (sv == NULL || len == NULL) { errno = EINVAL; return (-1); } /* the int s_port field is actually a short in network order. We want host order to make the marshalled data look correct */ realport = ntohs((short)sv->s_port); sprintf(svPort, "%d", realport); need += strlen(sv->s_name) + 1; need += joinlength(sv->s_aliases) + 1; need += strlen(svPort) + 1; need += strlen(sv->s_proto) + 1; if (buffer == NULL) { *len = need; return (0); } if (*buffer != NULL && need > *len) { errno = EINVAL; return (-1); } if (*buffer == NULL) { need += 2; /* for CRLF */ *buffer = memget(need); if (*buffer == NULL) { errno = ENOMEM; return (-1); } *len = need; } strcpy(*buffer, sv->s_name); strcat(*buffer, fieldsep); joinarray(sv->s_aliases, *buffer, COMMA); strcat(*buffer, fieldsep); strcat(*buffer, svPort); strcat(*buffer, fieldsep); strcat(*buffer, sv->s_proto); strcat(*buffer, fieldsep); return (0);}/* * int irp_unmarshall_sv(struct servent *sv, char *buffer) * * notes: * * see above * * return: * * 0 on success, -1 on failure. * */intirp_unmarshall_sv(struct servent *sv, char *buffer) { char *p, *q; short svport; long t; char *name = NULL; char *proto = NULL; char **aliases = NULL; char tmpbuf[24]; char *tb; char fieldsep = ':'; int myerrno = EINVAL; if (sv == NULL || buffer == NULL) return (-1); p = buffer; /* s_name field */ name = NULL; if (getfield(&name, 0, &p, fieldsep) == NULL || strlen(name) == 0U) { goto error; } /* s_aliases field */ q = strchr(p, fieldsep); if (q == NULL) { goto error; } aliases = splitarray(p, q, COMMA); if (aliases == NULL) { myerrno = errno; goto error; } p = q + 1; /* s_port field */ tb = tmpbuf; if (getfield(&tb, sizeof tmpbuf, &p, fieldsep) == NULL || strlen(tb) == 0U) { goto error; } t = strtol(tmpbuf, &tb, 10); if (*tb) { goto error; /* junk in value */ } svport = (short)t; if ((long) svport != t) { /* value must have been too big. */ goto error; } svport = htons(svport); /* s_proto field */ proto = NULL; if (getfield(&proto, 0, &p, fieldsep) == NULL) { goto error; } sv->s_name = name; sv->s_aliases = aliases; sv->s_port = svport; sv->s_proto = proto; return (0); error: errno = myerrno; if (name != NULL) free(name); if (proto != NULL) free(proto); free_array(aliases, 0); return (-1);}/* ------------------------- struct servent ------------------------- *//* +++++++++++++++++++++++++ struct protoent +++++++++++++++++++++++++ *//* * int irp_marshall_pr(struct protoent *pr, char **buffer, size_t *len) * * notes: * * see above * * return: * * 0 on success and -1 on failure. * */intirp_marshall_pr(struct protoent *pr, char **buffer, size_t *len) { size_t need = 1; /* for null byte */ char prProto[24]; const char *fieldsep = COLONSTR; if (pr == NULL || len == NULL) { errno = EINVAL; return (-1); } sprintf(prProto, "%d", (int)pr->p_proto); need += strlen(pr->p_name) + 1; need += joinlength(pr->p_aliases) + 1; need += strlen(prProto) + 1; if (buffer == NULL) { *len = need; return (0); } if (*buffer != NULL && need > *len) { errno = EINVAL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -