1*dc3f3e27Schristos /* $NetBSD: ypdb.c,v 1.12 2017/01/10 21:06:17 christos Exp $ */
260aa689cSthorpej
360aa689cSthorpej /*
460aa689cSthorpej * Copyright (c) 1990, 1993
560aa689cSthorpej * The Regents of the University of California. All rights reserved.
660aa689cSthorpej * All rights reserved.
760aa689cSthorpej *
860aa689cSthorpej * This code is derived from software contributed to Berkeley by
960aa689cSthorpej * Margo Seltzer.
1060aa689cSthorpej *
1160aa689cSthorpej * This code is derived from ndbm module of BSD4.4 db (hash) by
1260aa689cSthorpej * Mats O Jansson
1360aa689cSthorpej *
1460aa689cSthorpej * Redistribution and use in source and binary forms, with or without
1560aa689cSthorpej * modification, are permitted provided that the following conditions
1660aa689cSthorpej * are met:
1760aa689cSthorpej * 1. Redistributions of source code must retain the above copyright
1860aa689cSthorpej * notice, this list of conditions and the following disclaimer.
1960aa689cSthorpej * 2. Redistributions in binary form must reproduce the above copyright
2060aa689cSthorpej * notice, this list of conditions and the following disclaimer in the
2160aa689cSthorpej * documentation and/or other materials provided with the distribution.
22326b2259Sagc * 3. Neither the name of the University nor the names of its contributors
2360aa689cSthorpej * may be used to endorse or promote products derived from this software
2460aa689cSthorpej * without specific prior written permission.
2560aa689cSthorpej *
2660aa689cSthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
2760aa689cSthorpej * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2860aa689cSthorpej * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2960aa689cSthorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3060aa689cSthorpej * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3160aa689cSthorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3260aa689cSthorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3360aa689cSthorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3460aa689cSthorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3560aa689cSthorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3660aa689cSthorpej * SUCH DAMAGE.
3760aa689cSthorpej */
3860aa689cSthorpej
39652dc940Slukem #include <sys/cdefs.h>
40652dc940Slukem #ifndef lint
41*dc3f3e27Schristos __RCSID("$NetBSD: ypdb.c,v 1.12 2017/01/10 21:06:17 christos Exp $");
42652dc940Slukem #endif
43652dc940Slukem
4460aa689cSthorpej #include <sys/param.h>
4560aa689cSthorpej #include <sys/types.h>
46*dc3f3e27Schristos #include <sys/stat.h>
47652dc940Slukem
48652dc940Slukem #include <db.h>
49aa159e4aSlukem #include <err.h>
50652dc940Slukem #include <errno.h>
51cea4b7cdSlukem #include <fcntl.h>
5260aa689cSthorpej #include <stdio.h>
53cea4b7cdSlukem #include <stdlib.h>
5460aa689cSthorpej #include <string.h>
55cea4b7cdSlukem #include <unistd.h>
5660aa689cSthorpej
57f4fb444bSlukem #include <rpcsvc/yp.h>
58f4fb444bSlukem
593d8138fcSthorpej #include "ypdb.h"
6060aa689cSthorpej
61cea4b7cdSlukem static DBM *_ypdb_dbopen(const char *, int, mode_t);
62cea4b7cdSlukem
6360aa689cSthorpej /*
64aa159e4aSlukem * ypdb_open --
65cea4b7cdSlukem * dbopen(3) file, read-only.
66aa159e4aSlukem * First ensure that file has a suffix of YPDB_SUFFIX.
67aa159e4aSlukem * Try opening as a DB_BTREE first, then DB_HASH.
68aa159e4aSlukem *
6960aa689cSthorpej * Returns:
7060aa689cSthorpej * *DBM on success
7160aa689cSthorpej * NULL on failure
7260aa689cSthorpej */
7360aa689cSthorpej
74c0495ebbSlukem DBM *
ypdb_open(const char * file)75cea4b7cdSlukem ypdb_open(const char *file)
7660aa689cSthorpej {
77aa159e4aSlukem char path[MAXPATHLEN];
78aa159e4aSlukem const char *cp, *suffix;
7960aa689cSthorpej
80652dc940Slukem cp = strrchr(file, '.');
81aa159e4aSlukem if (cp != NULL && strcmp(cp, YPDB_SUFFIX) == 0)
82aa159e4aSlukem suffix = "";
83aa159e4aSlukem else
84aa159e4aSlukem suffix = YPDB_SUFFIX;
85aa159e4aSlukem if (strlen(file) + strlen(suffix) > (sizeof(path) - 1)) {
86aa159e4aSlukem warnx("File name `%s' is too long", file);
87aa159e4aSlukem return (NULL);
88aa159e4aSlukem }
89aa159e4aSlukem snprintf(path, sizeof(path), "%s%s", file, suffix);
90cea4b7cdSlukem return _ypdb_dbopen(path, O_RDONLY, 0444);
91cea4b7cdSlukem }
92cea4b7cdSlukem
93cea4b7cdSlukem /*
94cea4b7cdSlukem * ypdb_mktemp --
95cea4b7cdSlukem * Create a temporary file using mkstemp(3) based on the
96cea4b7cdSlukem * template provided in file.
97cea4b7cdSlukem * dbopen(3) file, read-write, 0644 (modified by umask(2)).
98cea4b7cdSlukem * Try opening as a DB_BTREE first, then DB_HASH.
99cea4b7cdSlukem * file won't have YPDB_SUFFIX.
100cea4b7cdSlukem *
101cea4b7cdSlukem * Returns:
102cea4b7cdSlukem * *DBM on success; file now exists.
103cea4b7cdSlukem * NULL on failure
104cea4b7cdSlukem */
105cea4b7cdSlukem
106cea4b7cdSlukem DBM *
ypdb_mktemp(char * file)107cea4b7cdSlukem ypdb_mktemp(char *file)
108cea4b7cdSlukem {
109cea4b7cdSlukem int fd = -1;
110cea4b7cdSlukem DBM *db = NULL;
111cea4b7cdSlukem mode_t myumask;
112cea4b7cdSlukem int save_errno;
113cea4b7cdSlukem
114cea4b7cdSlukem if ((fd = mkstemp(file)) == -1)
115cea4b7cdSlukem return NULL;
116cea4b7cdSlukem
117cea4b7cdSlukem myumask = umask(0);
118cea4b7cdSlukem (void)umask(myumask);
119cea4b7cdSlukem if (fchmod(fd, 0644 & ~myumask) == -1)
120cea4b7cdSlukem goto bad;
121cea4b7cdSlukem
122cea4b7cdSlukem (void) close(fd);
123cea4b7cdSlukem fd = -1;
124cea4b7cdSlukem
125cea4b7cdSlukem if ((db = _ypdb_dbopen(file, O_RDWR, 0644)) == NULL)
126cea4b7cdSlukem goto bad;
127cea4b7cdSlukem
128cea4b7cdSlukem return db;
129cea4b7cdSlukem
130cea4b7cdSlukem bad:
131cea4b7cdSlukem save_errno = errno;
132cea4b7cdSlukem if (fd != 1)
133cea4b7cdSlukem (void) close(fd);
134cea4b7cdSlukem (void) unlink(file);
135cea4b7cdSlukem errno = save_errno;
136cea4b7cdSlukem return NULL;
137cea4b7cdSlukem }
138cea4b7cdSlukem
139cea4b7cdSlukem /*
140cea4b7cdSlukem * _ypdb_dbopen --
141cea4b7cdSlukem * dbopen(3) path with the flags & mode.
142cea4b7cdSlukem * Try opening as a DB_BTREE first, then DB_HASH.
143cea4b7cdSlukem */
144cea4b7cdSlukem
145cea4b7cdSlukem static DBM *
_ypdb_dbopen(const char * path,int flags,mode_t mode)146cea4b7cdSlukem _ypdb_dbopen(const char *path, int flags, mode_t mode)
147cea4b7cdSlukem {
148cea4b7cdSlukem DBM *db;
149cea4b7cdSlukem BTREEINFO info;
150652dc940Slukem
151652dc940Slukem /* try our btree format first */
15260aa689cSthorpej info.flags = 0;
15360aa689cSthorpej info.cachesize = 0;
15460aa689cSthorpej info.maxkeypage = 0;
15560aa689cSthorpej info.minkeypage = 0;
15660aa689cSthorpej info.psize = 0;
15760aa689cSthorpej info.compare = NULL;
15860aa689cSthorpej info.prefix = NULL;
15960aa689cSthorpej info.lorder = 0;
160652dc940Slukem db = (DBM *)dbopen(path, flags, mode, DB_BTREE, (void *)&info);
161652dc940Slukem if (db != NULL || errno != EFTYPE)
162652dc940Slukem return (db);
163652dc940Slukem
164652dc940Slukem /* fallback to standard hash (for sendmail's aliases.db) */
165652dc940Slukem db = (DBM *)dbopen(path, flags, mode, DB_HASH, NULL);
166652dc940Slukem return (db);
16760aa689cSthorpej }
16860aa689cSthorpej
169cea4b7cdSlukem /*
170cea4b7cdSlukem * ypdb_close --
171cea4b7cdSlukem * Close the db
172cea4b7cdSlukem */
173cea4b7cdSlukem
174c0495ebbSlukem void
ypdb_close(DBM * db)1755c90fa67Swiz ypdb_close(DBM *db)
17660aa689cSthorpej {
17760aa689cSthorpej (void)(db->close)(db);
17860aa689cSthorpej }
17960aa689cSthorpej
18060aa689cSthorpej /*
18160aa689cSthorpej * Returns:
18260aa689cSthorpej * DATUM on success
18360aa689cSthorpej * NULL on failure
18460aa689cSthorpej */
18560aa689cSthorpej
186c0495ebbSlukem datum
ypdb_fetch(DBM * db,datum key)1875c90fa67Swiz ypdb_fetch(DBM *db, datum key)
18860aa689cSthorpej {
189275da9fcSlukem datum retkey;
190275da9fcSlukem DBT nk, nd;
19160aa689cSthorpej int status;
19260aa689cSthorpej
193275da9fcSlukem nk.data = key.dptr;
19481a3e762Slukem nk.size = key.dsize;
195275da9fcSlukem status = (db->get)(db, &nk, &nd, 0);
19660aa689cSthorpej if (status) {
197275da9fcSlukem retkey.dptr = NULL;
198275da9fcSlukem retkey.dsize = 0;
199275da9fcSlukem } else {
200275da9fcSlukem retkey.dptr = nd.data;
20181a3e762Slukem retkey.dsize = nd.size;
20260aa689cSthorpej }
203275da9fcSlukem return (retkey);
20460aa689cSthorpej }
20560aa689cSthorpej
20660aa689cSthorpej /*
20760aa689cSthorpej * Returns:
20860aa689cSthorpej * DATUM on success
20960aa689cSthorpej * NULL on failure
21060aa689cSthorpej */
21160aa689cSthorpej
212c0495ebbSlukem datum
ypdb_firstkey(DBM * db)2135c90fa67Swiz ypdb_firstkey(DBM *db)
21460aa689cSthorpej {
21560aa689cSthorpej int status;
216275da9fcSlukem datum retkey;
217275da9fcSlukem DBT nk, nd;
21860aa689cSthorpej
219275da9fcSlukem status = (db->seq)(db, &nk, &nd, R_FIRST);
220275da9fcSlukem if (status) {
22160aa689cSthorpej retkey.dptr = NULL;
222275da9fcSlukem retkey.dsize = 0;
223275da9fcSlukem } else {
224275da9fcSlukem retkey.dptr = nk.data;
22581a3e762Slukem retkey.dsize = nk.size;
226275da9fcSlukem }
22760aa689cSthorpej return (retkey);
22860aa689cSthorpej }
22960aa689cSthorpej
23060aa689cSthorpej /*
23160aa689cSthorpej * Returns:
23260aa689cSthorpej * DATUM on success
23360aa689cSthorpej * NULL on failure
23460aa689cSthorpej */
23560aa689cSthorpej
236c0495ebbSlukem datum
ypdb_nextkey(DBM * db)2375c90fa67Swiz ypdb_nextkey(DBM *db)
23860aa689cSthorpej {
23960aa689cSthorpej int status;
240275da9fcSlukem datum retkey;
241275da9fcSlukem DBT nk, nd;
24260aa689cSthorpej
243275da9fcSlukem status = (db->seq)(db, &nk, &nd, R_NEXT);
244275da9fcSlukem if (status) {
24560aa689cSthorpej retkey.dptr = NULL;
246275da9fcSlukem retkey.dsize = 0;
247275da9fcSlukem } else {
248275da9fcSlukem retkey.dptr = nk.data;
24981a3e762Slukem retkey.dsize = nk.size;
250275da9fcSlukem }
25160aa689cSthorpej return (retkey);
25260aa689cSthorpej }
25360aa689cSthorpej
25460aa689cSthorpej /*
25560aa689cSthorpej * Returns:
25660aa689cSthorpej * DATUM on success
25760aa689cSthorpej * NULL on failure
25860aa689cSthorpej */
25960aa689cSthorpej
260c0495ebbSlukem datum
ypdb_setkey(DBM * db,datum key)2615c90fa67Swiz ypdb_setkey(DBM *db, datum key)
26260aa689cSthorpej {
26360aa689cSthorpej int status;
264275da9fcSlukem DBT nk, nd;
265275da9fcSlukem
266275da9fcSlukem nk.data = key.dptr;
26781a3e762Slukem nk.size = key.dsize;
268275da9fcSlukem status = (db->seq)(db, &nk, &nd, R_CURSOR);
269275da9fcSlukem if (status) {
27060aa689cSthorpej key.dptr = NULL;
271275da9fcSlukem key.dsize = 0;
272275da9fcSlukem }
27360aa689cSthorpej return (key);
27460aa689cSthorpej }
27560aa689cSthorpej
27660aa689cSthorpej /*
27760aa689cSthorpej * Returns:
27860aa689cSthorpej * 0 on success
27960aa689cSthorpej * <0 failure
28060aa689cSthorpej */
28160aa689cSthorpej
28260aa689cSthorpej int
ypdb_delete(DBM * db,datum key)2835c90fa67Swiz ypdb_delete(DBM *db, datum key)
28460aa689cSthorpej {
28560aa689cSthorpej int status;
286275da9fcSlukem DBT nk;
28760aa689cSthorpej
288275da9fcSlukem nk.data = key.dptr;
28981a3e762Slukem nk.size = key.dsize;
290275da9fcSlukem status = (db->del)(db, &nk, 0);
29160aa689cSthorpej if (status)
29260aa689cSthorpej return (-1);
29360aa689cSthorpej else
29460aa689cSthorpej return (0);
29560aa689cSthorpej }
29660aa689cSthorpej
29760aa689cSthorpej /*
29860aa689cSthorpej * Returns:
29960aa689cSthorpej * 0 on success
30060aa689cSthorpej * <0 failure
30160aa689cSthorpej * 1 if YPDB_INSERT and entry exists
30260aa689cSthorpej */
30360aa689cSthorpej
30460aa689cSthorpej int
ypdb_store(DBM * db,datum key,datum content,int flags)3055c90fa67Swiz ypdb_store(DBM *db, datum key, datum content, int flags)
30660aa689cSthorpej {
307275da9fcSlukem DBT nk, nd;
308275da9fcSlukem
309f4fb444bSlukem if (key.dsize > YPMAXRECORD || content.dsize > YPMAXRECORD)
310f4fb444bSlukem return -1;
311275da9fcSlukem nk.data = key.dptr;
31281a3e762Slukem nk.size = key.dsize;
313275da9fcSlukem nd.data = content.dptr;
31481a3e762Slukem nd.size = content.dsize;
315275da9fcSlukem return ((db->put)(db, &nk, &nd,
31660aa689cSthorpej (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
31760aa689cSthorpej }
318