nis_util.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <shadow.h>
#include <stdlib.h>
/*
* nisname_index()
*
* Return pointer to place in string s of first match with char c.
* Do not match between quotes ("...").
*
* Totally rewritten as part of the fix for bug# 1263305.
* XXX - This can now probably be replaced by strchr_quotes().
*/
char *
nisname_index(char *s, char c)
{
do {
if (*s == '"') {
s++;
while (*s && *s != '"')
s++;
} else if (*s == c)
return (s);
} while (*s++);
return (NULL);
}
/*
* Parse a passed name into a basename and search criteria.
* if there is no criteria present the *crit == 0. You must
* pass in allocated data for the three strings.
*
* Returns 0 if successful, non-zero otherwise.
*/
int
char *name;
char *base;
char *crit;
int max_len;
{
register char *p, *q;
p = name;
while (*p && (isspace(*p)))
p++;
if (*p != '[') {
*crit = 0;
}
/* it has a criteria, copy the whole thing in */
return (1);
if (! q) {
*crit = 0; /* error condition */
*base = 0;
return (1);
}
q++;
if (*q == ',') {
*q = 0;
q++;
}
return (1);
*q = 0; /* just in case there wasn't a comma */
return (0);
}
nis_verifycred(n, flags)
nis_name n;
{
int err;
char dname[NIS_MAXNAMELEN];
nis_domain_of(n));
return (err);
}
static int
int shift;
char *p;
{
int set;
while (*p && (*p != ',')) {
switch (*p) {
case '=':
case '+':
set = 1;
break;
case '-':
set = 0;
break;
default:
return (0);
}
for (p++; *p && (*p != ',') && (*p != '=') && (*p != '+') &&
(*p != '-'); p++) {
switch (*p) {
case 'r':
if (set)
else
break;
case 'm':
if (set)
else
break;
case 'c':
if (set)
else
break;
case 'd':
if (set)
else
break;
default:
return (0);
}
}
}
return (1);
}
#define NIS_NOBODY_FLD 1
#define NIS_OWNER_FLD 2
#define NIS_GROUP_FLD 4
#define NIS_WORLD_FLD 8
int
parse_rights(rights, p)
char *p;
{
uint_t f;
if (p)
while (*p) {
for (f = 0; (*p != '=') && (*p != '+') && (*p != '-');
p++)
switch (*p) {
case 'n':
f |= NIS_NOBODY_FLD;
break;
case 'o':
f |= NIS_OWNER_FLD;
break;
case 'g':
f |= NIS_GROUP_FLD;
break;
case 'w':
f |= NIS_WORLD_FLD;
break;
case 'a':
f |= NIS_ALL_FLD;
break;
default:
return (0);
}
if (f == 0)
f = NIS_ALL_FLD;
if ((f & NIS_NOBODY_FLD) &&
return (0);
if ((f & NIS_OWNER_FLD) &&
return (0);
if ((f & NIS_GROUP_FLD) &&
return (0);
if ((f & NIS_WORLD_FLD) &&
!parse_rights_field(rights, 0, p))
return (0);
while (*(++p))
if (*p == ',') {
p++;
break;
}
}
return (1);
}
int
parse_flags(flags, p)
char *p;
{
if (p) {
while (*p) {
switch (*(p++)) {
case 'B':
break;
case 'X':
break;
case 'S':
*flags |= TA_SEARCHABLE;
break;
case 'I':
break;
case 'C':
break;
default:
return (0);
}
}
return (1);
} else {
"Invalid table schema: At least one column must be searchable.\n");
exit(1);
}
}
int
parse_time(time, p)
char *p;
{
char *s;
uint32_t x;
*time = 0;
if (p)
while (*p) {
if (!isdigit(*p))
return (0);
x = strtol(p, &s, 10);
switch (*s) {
case '\0':
(*time) += x;
p = s;
break;
case 's':
case 'S':
(*time) += x;
p = s+1;
break;
case 'm':
case 'M':
(*time) += x*60;
p = s+1;
break;
case 'h':
case 'H':
p = s+1;
break;
case 'd':
case 'D':
p = s+1;
break;
default:
return (0);
}
}
return (1);
}
static int
char **optionsp;
char * const *tokens;
const int sep; /* if this is a char we get an alignment error */
char **valuep;
{
register char *s = *optionsp, *p, *q;
register int i, optlen;
if (*s == '\0')
return (-1);
if (q == NULL) {
q = s + strlen(s);
} else {
*q++ = '\0'; /* mark end and point to next */
}
if (p == NULL) {
} else {
optlen = p - s;
*valuep = ++p;
}
/* point to next option only if success */
*optionsp = q;
return (i);
}
}
/* no match, point value at option and return error */
*valuep = s;
return (-1);
}
/*
* We record the source of the defaults.
* 0 => default
* 1 => from NIS_DEFAULTS env variable
* 2 => from arg passed to nis_defaults_init
*/
#define NIS_SRC_DEFAULT 0
#define NIS_SRC_ENV 1
#define NIS_SRC_ARG 2
static char *nis_defaults_tokens[] = {
"owner",
"group",
"access",
"ttl",
0
};
#define T_OWNER 0
#define T_GROUP 1
#define T_ACCESS 2
#define T_TTL 3
static int
char *optstr;
int src;
{
char str[1024], *p, *v;
int i;
return (0);
p = str;
switch (i) {
case T_OWNER:
return (0);
break;
case T_GROUP:
return (0);
break;
case T_ACCESS:
if ((v == 0) ||
return (0);
break;
case T_TTL:
if ((v == 0) ||
return (0);
break;
}
}
if (*p)
return (0);
return (1);
}
extern char *getenv();
int
char *optstr;
{
char *envstr;
/* XXX calling this multiple times may leak memory */
"can't parse NIS_DEFAULTS environment variable.\n");
return (0);
}
if (optstr)
return (0);
}
return (1);
}
/*
* Converts an NIS+ entry object for a passwd table to its
* pwent structure.
* XXX: This function returns a pointer to a static structure.
*/
static struct passwd *
{
static char nullstring; /* used for NULL data */
char *tmp;
char *end;
*error = NIS_INVALIDOBJ;
return (NULL);
}
*error = NIS_INVALIDOBJ;
return (NULL);
} else {
}
} else {
/* XXX: Should I be returning X here? */
}
*error = NIS_INVALIDOBJ;
return (NULL);
}
else
} else {
}
} else {
}
} else {
}
*error = NIS_SUCCESS;
return (&pw);
}
/*
* This will go to the NIS+ master to get the data. This code
* is ugly because the internals of the switch had to be opened
* up here. Wish there was a way to pass a MASTER_ONLY flag
* to getpwuid() and all such getXbyY() calls. Some of this code
* is being copied from the NIS+ switch backend.
*
* XXX: We will not bother to make this MT-safe. If any of the callers
* for this function want to use getpwuid_r(), then a corresponding
* function will have to written.
*/
struct passwd *
char *domain;
{
struct passwd *passwd_ent;
char namebuf[NIS_MAXNAMELEN];
*error = NIS_NOMEMORY;
return (NULL);
}
return (NULL);
}
if (NIS_RES_NUMOBJ(res) == 0) {
*error = NIS_NOTFOUND;
return (NULL);
}
return (passwd_ent);
}
/*
* Converts an NIS+ entry object for a shadow table to its
* spwent structure. We only fill in the sp_namp and sp_pwdp fields.
* XXX: This function returns a pointer to a static structure.
*/
static struct spwd *
{
static char nullstring; /* used for NULL data */
char *tmp;
char *end;
*error = NIS_INVALIDOBJ;
return (NULL);
}
*error = NIS_INVALIDOBJ;
return (NULL);
} else {
}
} else {
}
*error = NIS_SUCCESS;
return (&spw);
}
/*
* This will go to the NIS+ master to get the data. This code
* is ugly because the internals of the switch had to be opened
* up here. Wish there was a way to pass a MASTER_ONLY flag
* to getspnam() and all such getXbyY() calls. Some of this code
* is being copied from the NIS+ switch backend.
*
* XXX: We will not bother to make this MT-safe. If any of the callers
* for this function want to use getpwuid_r(), then a corresponding
* function will have to written.
*/
struct spwd *
char *domain;
char *name;
{
struct spwd *shadow_ent;
char namebuf[NIS_MAXNAMELEN];
*error = NIS_NOMEMORY;
return (NULL);
}
return (NULL);
}
if (NIS_RES_NUMOBJ(res) == 0) {
*error = NIS_NOTFOUND;
return (NULL);
}
return (shadow_ent);
}
/* begin bug# 1263305 */
/*
* __nis_quote_key()
*
* Enclose NIS+ terminating characters ']' and ',' within '"' and
* escape '"' by doubling it so the string is safe to pass to
* nis_list(3N) and associated routines. For example, a src string
* of "foo[]bar" will result in a dst string of ""foo["]"bar""
*/
char *
{
int dstleft;
switch (*src) {
case ']':
case ',':
/* quote the character */
*dst++ = '"';
*dst++ = '"';
dstleft -= 3;
break;
case '"':
/* double the quote */
*dst++ = '"';
dstleft--;
/* fall through... */
default:
dstleft--;
break;
}
}
*dst = '\0';
if (*src)
"nis_quote_key: warning: src string too long\n");
return (dstorig);
}
/*
* *str* routines below originated in libc.
*/
/*
* strpbrk_quotes()
*
* Like strpbrk except it will not match target chars inside quoted
* strings ("...").
*/
char *
{
register const char *p;
do {
++p)
;
if (*string == '"') {
string++;
string++;
} else if (*p != '\0')
return ((char *)string);
}
while (*string++);
return (NULL);
}
/*
* strtok_r_quotes()
*
* uses strpbrk_quotes and strspn to break string into tokens on
* sequentially subsequent calls. returns NULL when no
* non-separator characters remain.
* `subsequent' calls are calls with first argument NULL.
*
*/
static char *
{
char *q, *r;
/* first or subsequent call */
if (string == 0) /* return if no tokens remaining */
return (NULL);
if (*q == '\0') /* return if no tokens remaining */
return (NULL);
*lasts = 0; /* indicate this is last token */
else {
*r = '\0';
*lasts = r+1;
}
return (q);
}
/*
* strtok_quotes()
*
* Like strtok except it will not match target chars within quoted
* strings ("...").
*/
char *
{
static char *lasts;
}
/*
* strchr_quotes()
*
* Like strchr but will not match within quoted strings ("...").
*/
char *
strchr_quotes(char *s, char c)
{
do {
if (*s == '"') {
s++;
while (*s && *s != '"')
s++;
} else if (*s == c)
return (s);
} while (*s++);
return (NULL);
}
/* end bug# 1263305 */