static int get_local_ordernum(char *domain, char *map, u_int32_t *lordernum) { char map_path[MAXPATHLEN], order[MAX_LAST_LEN+1]; char order_key[] = YP_LAST_KEY; struct stat finfo; datum k, v; int status; DBM *db; /* This routine returns YPPUSH_SUCC or YPPUSH_NODOM */ status = YPPUSH_SUCC; snprintf(map_path, sizeof map_path, "%s/%s", YP_DB_PATH, domain); if (!((stat(map_path, &finfo) == 0) && S_ISDIR(finfo.st_mode))) { fprintf(stderr, "ypxfr: domain %s not found locally\n", domain); status = YPPUSH_NODOM; goto bail; } snprintf(map_path, sizeof map_path, "%s/%s/%s%s", YP_DB_PATH, domain, map, YPDB_SUFFIX); if (!(stat(map_path, &finfo) == 0)) { status = YPPUSH_NOMAP; goto bail; } snprintf(map_path, sizeof map_path, "%s/%s/%s", YP_DB_PATH, domain, map); db = ypdb_open(map_path, O_RDONLY, 0444); if (db == NULL) { status = YPPUSH_DBM; goto bail; } k.dptr = (char *)&order_key; k.dsize = YP_LAST_LEN; v = ypdb_fetch(db, k); if (v.dptr == NULL) { *lordernum = 0; } else { strlcpy(order, v.dptr, sizeof order); *lordernum = (u_int32_t)atol(order); } ypdb_close(db); bail: if (status == YPPUSH_NOMAP || status == YPPUSH_DBM) { *lordernum = 0; status = YPPUSH_SUCC; } return (status); }
int main(int argc, char *argv[]) { int eflag = 0, dflag = 0, nflag = 0; int uflag = 0, vflag = 0, Eflag = 0; int status, ch, fd; char *input = NULL, *output = NULL; DBM *db; datum key, val; DBM *new_db = NULL; static char mapname[] = "ypdbXXXXXXXXXX"; char db_mapname[PATH_MAX], db_outfile[PATH_MAX]; char db_tempname[PATH_MAX]; char user[4096], host[4096]; /* XXX: DB bsize = 4096 in ypdb.c */ char myname[HOST_NAME_MAX+1], datestr[11], *slash; while ((ch = getopt(argc, argv, "Edensuv")) != -1) switch (ch) { case 'E': eflag = 1; /* Check hostname */ Eflag = 1; /* .. even check MX records */ break; case 'd': dflag = 1; /* Don't check DNS hostname */ break; case 'e': eflag = 1; /* Check hostname */ break; case 'n': nflag = 1; /* Capitalize name parts */ break; case 's': /* Ignore */ break; case 'u': uflag = 1; /* Don't check UUCP hostname */ break; case 'v': vflag = 1; /* Verbose */ break; default: usage(); break; } if (optind == argc) usage(); input = argv[optind++]; if (optind < argc) output = argv[optind++]; if (optind < argc) usage(); db = ypdb_open(input, O_RDONLY, 0444); if (db == NULL) { err(1, "Unable to open input database %s", input); /* NOTREACHED */ } if (output != NULL) { if (strlen(output) + strlen(YPDB_SUFFIX) > PATH_MAX) { errx(1, "%s: file name too long", output); /* NOTREACHED */ } snprintf(db_outfile, sizeof(db_outfile), "%s%s", output, YPDB_SUFFIX); slash = strrchr(output, '/'); if (slash != NULL) slash[1] = 0; /* truncate to dir */ else *output = 0; /* eliminate */ /* note: output is now directory where map goes ! */ if (strlen(output) + strlen(mapname) + strlen(YPDB_SUFFIX) > PATH_MAX) { errx(1, "%s: directory name too long", output); /* NOTREACHED */ } snprintf(db_tempname, sizeof(db_tempname), "%s%s%s", output, mapname, YPDB_SUFFIX); fd = mkstemps(db_tempname, 3); if (fd == -1) goto fail; close(fd); strncpy(db_mapname, db_tempname, strlen(db_tempname) - 3); db_mapname[sizeof(db_mapname) - 1] = '\0'; new_db = ypdb_open(db_mapname, O_RDWR|O_TRUNC, 0444); if (new_db == NULL) { fail: if (fd != -1) unlink(db_tempname); err(1, "Unable to open output database %s", db_outfile); /* NOTREACHED */ } } for (key = ypdb_firstkey(db); key.dptr != NULL; key = ypdb_nextkey(db)) { val = ypdb_fetch(db, key); if (val.dptr == NULL) continue; /* No value */ if (*key.dptr == '@' && key.dsize == 1) continue; /* Sendmail token */ if (strncmp(key.dptr, "YP_", 3)==0) /* YP token */ continue; if (memchr(val.dptr, ',', val.dsize)) continue; /* List... */ if (memchr(val.dptr, '|', val.dsize)) continue; /* Pipe... */ if (!(memchr(val.dptr, '@', val.dsize) || memchr(val.dptr, '!', val.dsize))) continue; /* Skip local users */ split_address(val.dptr, val.dsize, user, host); if (eflag && check_host(val.dptr, val.dsize, host, dflag, uflag, Eflag)) { warnx("Invalid host %s in %*.*s:%*.*s", host, key.dsize, key.dsize, key.dptr, val.dsize, val.dsize, val.dptr); continue; } if (nflag) capitalize(key.dptr, key.dsize); if (new_db != NULL) { status = ypdb_store(new_db, val, key, YPDB_INSERT); if (status != 0) { warnx("problem storing %*.*s %*.*s", val.dsize, val.dsize, val.dptr, key.dsize, key.dsize, key.dptr); } } if (vflag) { printf("%*.*s --> %*.*s\n", val.dsize, val.dsize, val.dptr, key.dsize, key.dsize, key.dptr); } } if (new_db != NULL) { snprintf(datestr, sizeof datestr, "%010lld", (long long)time(NULL)); key.dptr = YP_LAST_KEY; key.dsize = strlen(YP_LAST_KEY); val.dptr = datestr; val.dsize = strlen(datestr); status = ypdb_store(new_db, key, val, YPDB_INSERT); if (status != 0) { warnx("problem storing %*.*s %*.*s", key.dsize, key.dsize, key.dptr, val.dsize, val.dsize, val.dptr); } } if (new_db != NULL) { gethostname(myname, sizeof(myname)); key.dptr = YP_MASTER_KEY; key.dsize = strlen(YP_MASTER_KEY); val.dptr = myname; val.dsize = strlen(myname); status = ypdb_store(new_db, key, val, YPDB_INSERT); if (status != 0) { warnx("problem storing %*.*s %*.*s", key.dsize, key.dsize, key.dptr, val.dsize, val.dsize, val.dptr); } } ypdb_close(db); if (new_db != NULL) { ypdb_close(new_db); if (rename(db_tempname, db_outfile) < 0) { err(1, "rename %s -> %s failed", db_tempname, db_outfile); /* NOTREACHED */ } } return(0); }
/* * ypdb_open_db */ DBM * ypdb_open_db(const char *domain, const char *map, u_int *status, struct opt_map **map_info) { static const char *domain_key = YP_INTERDOMAIN_KEY; static const char *secure_key = YP_SECURE_KEY; char map_path[MAXPATHLEN]; struct stat finfo; struct opt_domain *d = NULL; struct opt_map *m = NULL; DBM *db; datum k, v; *status = YP_TRUE; /* defaults to true */ /* * check for illegal domain and map names */ if (_yp_invalid_domain(domain)) { *status = YP_NODOM; return (NULL); } if (_yp_invalid_map(map)) { *status = YP_NOMAP; return (NULL); } /* * check for domain, file. */ (void)snprintf(map_path, sizeof(map_path), "%s/%s", YP_DB_PATH, domain); if (stat(map_path, &finfo) < 0 || !S_ISDIR(finfo.st_mode)) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: no domain %s (map=%s)", domain, map); #endif *status = YP_NODOM; } else { (void)snprintf(map_path, sizeof(map_path), "%s/%s/%s%s", YP_DB_PATH, domain, map, YPDB_SUFFIX); if (stat(map_path, &finfo) < 0) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: no map %s (domain=%s)", map, domain); #endif *status = YP_NOMAP; } } /* * check for preloaded domain, map */ for (d = doms.lh_first; d != NULL; d = d->domsl.le_next) if (strcmp(domain, d->domain) == 0) break; if (d) for (m = d->dmaps.lh_first; m != NULL; m = m->mapsl.le_next) if (strcmp(map, m->map) == 0) break; /* * map found open? */ if (m) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: cached open: domain=%s, map=%s, db=%p,", domain, map, m->db); syslog(LOG_DEBUG, "\tdbdev %d new %d; dbino %d new %d; dbmtime %ld new %ld", m->dbdev, finfo.st_dev, m->dbino, finfo.st_ino, (long) m->dbmtime, (long) finfo.st_mtime); #endif /* * if status != YP_TRUE, then this cached database is now * non-existent */ if (*status != YP_TRUE) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: cached db is now unavailable - " "closing: status %s", yperr_string(ypprot_err(*status))); #endif ypdb_close_map(m); return (NULL); } /* * is this the same db? */ if (finfo.st_dev == m->dbdev && finfo.st_ino == m->dbino && finfo.st_mtime == m->dbmtime) { CIRCLEQ_REMOVE(&maps, m, mapsq); /* adjust LRU queue */ CIRCLEQ_INSERT_HEAD(&maps, m, mapsq); if (map_info) *map_info = m; return (m->db); } else { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: db changed; closing"); #endif ypdb_close_map(m); m = NULL; } } /* * not cached and non-existent, return */ if (*status != YP_TRUE) return (NULL); /* * open map */ (void)snprintf(map_path, sizeof(map_path), "%s/%s/%s", YP_DB_PATH, domain, map); #ifdef OPTIMIZE_DB retryopen: #endif /* OPTIMIZE_DB */ db = ypdb_open(map_path); #ifdef OPTIMIZE_DB if (db == NULL) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: errno %d (%s)", errno, strerror(errno)); #endif /* DEBUG */ if ((errno == ENFILE) || (errno == EMFILE)) { ypdb_close_last(); goto retryopen; } } #endif /* OPTIMIZE_DB */ *status = YP_NOMAP; /* see note below */ if (db == NULL) { #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: ypdb_open FAILED: map %s (domain=%s)", map, domain); #endif return (NULL); } /* * note: status now YP_NOMAP */ if (d == NULL) { /* allocate new domain? */ d = (struct opt_domain *) malloc(sizeof(*d)); if (d) d->domain = strdup(domain); if (d == NULL || d->domain == NULL) { syslog(LOG_ERR, "ypdb_open_db: MALLOC failed"); ypdb_close(db); if (d) free(d); return (NULL); } LIST_INIT(&d->dmaps); LIST_INSERT_HEAD(&doms, d, domsl); #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: NEW DOMAIN %s", domain); #endif } /* * m must be NULL since we couldn't find a map. allocate new one */ m = (struct opt_map *) malloc(sizeof(*m)); if (m) m->map = strdup(map); if (m == NULL || m->map == NULL) { if (m) free(m); syslog(LOG_ERR, "ypdb_open_db: MALLOC failed"); ypdb_close(db); return (NULL); } m->db = db; m->dom = d; m->host_lookup = FALSE; m->dbdev = finfo.st_dev; m->dbino = finfo.st_ino; m->dbmtime = finfo.st_mtime; CIRCLEQ_INSERT_HEAD(&maps, m, mapsq); LIST_INSERT_HEAD(&d->dmaps, m, mapsl); if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) { if (!usedns) { k.dptr = domain_key; k.dsize = YP_INTERDOMAIN_LEN; v = ypdb_fetch(db, k); if (v.dptr) m->host_lookup = TRUE; } else m->host_lookup = TRUE; } m->secure = FALSE; k.dptr = secure_key; k.dsize = YP_SECURE_LEN; v = ypdb_fetch(db, k); if (v.dptr != NULL) m->secure = TRUE; *status = YP_TRUE; if (map_info) *map_info = m; #ifdef DEBUG syslog(LOG_DEBUG, "ypdb_open_db: NEW MAP domain=%s, map=%s, hl=%d, s=%d, db=%p", domain, map, m->host_lookup, m->secure, m->db); #endif return (m->db); }
int main(int argc, char *argv[]) { struct ypall_callback ypcb; extern char *optarg; extern int optind; char *domain, *map, *hostname; int c, r, i; char *ypmap = "ypservers"; CLIENT *client; static char map_path[MAXPATHLEN]; struct stat finfo; DBM *yp_databas; char order_key[YP_LAST_LEN] = YP_LAST_KEY; datum o; yp_get_default_domain(&domain); hostname = NULL; while ((c=getopt(argc, argv, "d:h:v")) != -1) switch (c) { case 'd': domain = optarg; break; case 'h': hostname = optarg; break; case 'v': Verbose = 1; break; default: usage(); /*NOTREACHED*/ } if (optind + 1 != argc ) usage(); map = argv[optind]; strncpy(Domain, domain, sizeof(Domain)-1); Domain[sizeof(Domain)-1] = '\0'; strncpy(Map, map, sizeof(Map)-1); Map[sizeof(Map)-1] = '\0'; /* Check domain */ snprintf(map_path, sizeof map_path, "%s/%s", YP_DB_PATH, domain); if (!((stat(map_path, &finfo) == 0) && S_ISDIR(finfo.st_mode))) { fprintf(stderr, "yppush: Map does not exist.\n"); exit(1); } /* Check map */ snprintf(map_path, sizeof map_path, "%s/%s/%s%s", YP_DB_PATH, domain, Map, YPDB_SUFFIX); if (!(stat(map_path, &finfo) == 0)) { fprintf(stderr, "yppush: Map does not exist.\n"); exit(1); } snprintf(map_path, sizeof map_path, "%s/%s/%s", YP_DB_PATH, domain, Map); yp_databas = ypdb_open(map_path, 0, O_RDONLY); OrderNum=0xffffffff; if (yp_databas == 0) { fprintf(stderr, "yppush: %s%s: Cannot open database\n", map_path, YPDB_SUFFIX); } else { o.dptr = (char *) &order_key; o.dsize = YP_LAST_LEN; o = ypdb_fetch(yp_databas, o); if (o.dptr == NULL) { fprintf(stderr, "yppush: %s: Cannot determine order number\n", Map); } else { OrderNum=0; for (i=0; i<o.dsize-1; i++) { if (!isdigit(o.dptr[i])) OrderNum=0xffffffff; } if (OrderNum != 0) { fprintf(stderr, "yppush: %s: Invalid order number '%s'\n", Map, o.dptr); } else { OrderNum = atoi(o.dptr); } } } yp_bind(Domain); r = yp_master(Domain, ypmap, &master); if (r != 0) { fprintf(stderr, "yppush: could not get ypservers map\n"); exit(1); } if (hostname != NULL) { push(strlen(hostname), hostname); } else { if (Verbose) { printf("Contacting master for ypservers (%s).\n", master); } client = yp_bind_host(master, YPPROG, YPVERS, 0, 1); ypcb.foreach = pushit; ypcb.data = NULL; r = yp_all_host(client, Domain, ypmap, &ypcb); } exit(0); }