/* * Initialize the device policy code */ void devpolicy_init(void) { rw_init(&policyrw, NULL, RW_DRIVER, NULL); mutex_init(&policymutex, NULL, MUTEX_DRIVER, NULL); /* The mutex is held here in order to satisfy the ASSERT in dpget() */ mutex_enter(&policymutex); nullpolicy = dpget(); dfltpolicy = dpget(); netpolicy = dpget(); /* * Initially, we refuse access to all devices except * to processes with all privileges. */ priv_fillset(&dfltpolicy->dp_rdp); priv_fillset(&dfltpolicy->dp_wrp); totitems = 1; devplcy_gen++; mutex_exit(&policymutex); /* initialize default network privilege */ priv_emptyset(&netpolicy->dp_rdp); priv_emptyset(&netpolicy->dp_wrp); priv_addset(&netpolicy->dp_rdp, PRIV_NET_RAWACCESS); priv_addset(&netpolicy->dp_wrp, PRIV_NET_RAWACCESS); }
bool DBPrivAdvanceCursor(DBCursorPriv *cursor, void **key, int *ksize, void **value, int *vsize) { if (!Lock(cursor->db)) { return false; } free(cursor->curkey); free(cursor->curval); cursor->curkey = NULL; cursor->curval = NULL; *key = dpiternext(cursor->db->depot, ksize); if (*key == NULL) { /* Reached the end of database */ Unlock(cursor->db); return false; } *value = dpget(cursor->db->depot, *key, *ksize, 0, -1, vsize); // keep pointers for later free cursor->curkey = *key; cursor->curkey_size = *ksize; cursor->curval = *value; Unlock(cursor->db); return true; }
/* Retrieve a record. */ datum gdbm_fetch(GDBM_FILE dbf, datum key){ datum content; char *vbuf; int vsiz; assert(dbf); if(!key.dptr || key.dsize < 0){ gdbm_errno = GDBM_ILLEGAL_DATA; content.dptr = NULL; content.dsize = 0; return content; } if(dbf->depot){ if(!(vbuf = dpget(dbf->depot, key.dptr, key.dsize, 0, -1, &vsiz))){ gdbm_errno = gdbm_geterrno(dpecode); content.dptr = NULL; content.dsize = 0; return content; } } else { if(!(vbuf = crget(dbf->curia, key.dptr, key.dsize, 0, -1, &vsiz))){ gdbm_errno = gdbm_geterrno(dpecode); content.dptr = NULL; content.dsize = 0; return content; } } content.dptr = vbuf; content.dsize = vsiz; return content; }
/* * Return device privileges by privilege name * Called by ddi_create_priv_minor_node() */ devplcy_t * devpolicy_priv_by_name(const char *read_priv, const char *write_priv) { devplcy_t *dp; mutex_enter(&policymutex); dp = dpget(); mutex_exit(&policymutex); priv_str_to_set(read_priv, &dp->dp_rdp); priv_str_to_set(write_priv, &dp->dp_wrp); return (dp); }
static VALUE minidb_get(VALUE self, VALUE key) { DEPOT *db; char *p; int len; VALUE str; Data_Get_Struct(self, DEPOT, db); StringValue(key); p = dpget(db, RSTRING_PTR(key), RSTRING_LEN(key), 0, -1, &len); str = rb_tainted_str_new(p, len); free(p); return str; }
/* perform export command */ int doexport(const char *name, int bin){ DEPOT *depot; char *kbuf, *vbuf, *tmp; int err, ksiz, vsiz; /* open a database */ if(!(depot = dpopen(name, DP_OREADER, -1))){ pdperror(name); return 1; } /* initialize the iterator */ dpiterinit(depot); /* loop for each key */ err = FALSE; while((kbuf = dpiternext(depot, &ksiz)) != NULL){ /* retrieve a value with a key */ if(!(vbuf = dpget(depot, kbuf, ksiz, 0, -1, &vsiz))){ pdperror(name); free(kbuf); err = TRUE; break; } /* output data */ if(bin){ tmp = cbbaseencode(kbuf, ksiz); printf("%s\t", tmp); free(tmp); tmp = cbbaseencode(vbuf, vsiz); printf("%s\n", tmp); free(tmp); } else { printf("%s\t%s\n", kbuf, vbuf); } /* free resources */ free(vbuf); free(kbuf); } /* check whether all records were retrieved */ if(dpecode != DP_ENOITEM){ pdperror(name); err = TRUE; } /* close the database */ if(!dpclose(depot)){ pdperror(name); return 1; } return err ? 1 : 0; }
static devplcyent_t * parse_policy(devplcysys_t *ds, devplcy_t *nullp, devplcy_t *defp) { devplcyent_t *de = kmem_zalloc(sizeof (*de), KM_SLEEP); devplcy_t *np; if (priv_isemptyset(&ds->dps_rdp) && priv_isemptyset(&ds->dps_wrp)) dphold(np = nullp); else if (defp != nullp && priv_isequalset(&ds->dps_rdp, &defp->dp_rdp) && priv_isequalset(&ds->dps_wrp, &defp->dp_wrp)) dphold(np = defp); else { np = dpget(); np->dp_rdp = ds->dps_rdp; np->dp_wrp = ds->dps_wrp; } if (ds->dps_minornm[0] != '\0') { de->dpe_len = strlen(ds->dps_minornm) + 1; if (strchr(ds->dps_minornm, '*') != NULL) { if (de->dpe_len == 2) { /* "*\0" */ de->dpe_flags = DPE_ALLMINOR; de->dpe_len = 0; } else de->dpe_flags = DPE_WILDC; } if (de->dpe_len != 0) { de->dpe_expr = kmem_alloc(de->dpe_len, KM_SLEEP); (void) strcpy(de->dpe_expr, ds->dps_minornm); } } else { de->dpe_lomin = ds->dps_lomin; de->dpe_himin = ds->dps_himin; de->dpe_flags = DPE_EXPANDED; de->dpe_spec = ds->dps_isblock ? VBLK : VCHR; } de->dpe_plcy = np; ASSERT((de->dpe_flags & (DPE_ALLMINOR|DPE_EXPANDED)) || de->dpe_expr != NULL); return (de); }
/* * Load the device policy. * The device policy currently makes nu distinction between the * block and characters devices; that is generally not a problem * as the names of those devices cannot clash. */ int devpolicy_load(int nitems, size_t sz, devplcysys_t *uitmp) { int i, j; int nmaj = 0; major_t lastmajor; devplcysys_t *items; size_t mem; major_t curmaj; devplcyent_t **last, *de; tableent_t *newpolicy, *oldpolicy; devplcy_t *newnull, *newdflt, *oldnull, *olddflt; int oldcnt; int lastlen; int lastwild; #ifdef lint /* Lint can't figure out that the "i == 1" test protects all */ lastlen = 0; lastwild = 0; lastmajor = 0; #endif /* * The application must agree with the kernel on the size of each * item; it must not exceed the maximum number and must be * at least 1 item in size. */ if (sz != sizeof (devplcysys_t) || nitems > maxdevpolicy || nitems < 1) return (EINVAL); mem = nitems * sz; items = kmem_alloc(mem, KM_SLEEP); if (copyin(uitmp, items, mem)) { kmem_free(items, mem); return (EFAULT); } /* Check for default policy, it must exist and be sorted first */ if (items[0].dps_maj != DEVPOLICY_DFLT_MAJ) { kmem_free(items, mem); return (EINVAL); } /* * Application must deliver entries sorted. * Sorted meaning here: * In major number order * For each major number, we first need to have the explicit * entries, then the wild card entries, longest first. */ for (i = 1; i < nitems; i++) { int len, wild; char *tmp; curmaj = items[i].dps_maj; len = strlen(items[i].dps_minornm); wild = len > 0 && (tmp = strchr(items[i].dps_minornm, '*')) != NULL; /* Another default major, string too long or too many ``*'' */ if (curmaj == DEVPOLICY_DFLT_MAJ || len >= sizeof (items[i].dps_minornm) || wild && strchr(tmp + 1, '*') != NULL) { kmem_free(items, mem); return (EINVAL); } if (i == 1 || lastmajor < curmaj) { lastmajor = curmaj; nmaj++; } else if (lastmajor > curmaj || lastwild > wild || lastwild && lastlen < len) { kmem_free(items, mem); return (EINVAL); } lastlen = len; lastwild = wild; } if (AU_AUDITING()) audit_devpolicy(nitems, items); /* * Parse the policy. We create an array for all major numbers * and in each major number bucket we'll have a linked list of * entries. Each item may contain either a lo,hi minor pair * or a string/wild card matching a minor node. */ if (nmaj > 0) newpolicy = kmem_zalloc(nmaj * sizeof (tableent_t), KM_SLEEP); /* * We want to lock out concurrent updates but we don't want to * lock out device opens while we still need to allocate memory. * As soon as we allocate new devplcy_t's we commit to the next * generation number, so we must lock out other updates from here. */ mutex_enter(&policymutex); /* New default and NULL policy */ newnull = dpget(); if (priv_isemptyset(&items[0].dps_rdp) && priv_isemptyset(&items[0].dps_wrp)) { newdflt = newnull; dphold(newdflt); } else { newdflt = dpget(); newdflt->dp_rdp = items[0].dps_rdp; newdflt->dp_wrp = items[0].dps_wrp; } j = -1; /* Userland made sure sorting was ok */ for (i = 1; i < nitems; i++) { de = parse_policy(&items[i], newnull, newdflt); if (j == -1 || curmaj != items[i].dps_maj) { j++; newpolicy[j].t_major = curmaj = items[i].dps_maj; last = &newpolicy[j].t_ent; } *last = de; last = &de->dpe_next; } /* Done parsing, throw away input */ kmem_free(items, mem); /* Lock out all devpolicy_find()s */ rw_enter(&policyrw, RW_WRITER); /* Install the new global data */ oldnull = nullpolicy; nullpolicy = newnull; olddflt = dfltpolicy; dfltpolicy = newdflt; oldcnt = ntabent; ntabent = nmaj; totitems = nitems; oldpolicy = devpolicy; devpolicy = newpolicy; /* Force all calls by devpolicy_find() */ devplcy_gen++; /* Reenable policy finds */ rw_exit(&policyrw); mutex_exit(&policymutex); /* Free old stuff */ if (oldcnt != 0) { for (i = 0; i < oldcnt; i++) freechain(oldpolicy[i].t_ent); kmem_free(oldpolicy, oldcnt * sizeof (*oldpolicy)); } dpfree(oldnull); dpfree(olddflt); return (0); }
int main(int argc, char *argv[]) { DEPOT *dbmap = NULL; char *str_prefix = "dbbm_key_prefix_"; char *key, keystr[24]; unsigned long i; int rc = 0; PDUMMY_DATA datap; if (argc < 3) { fprintf(stderr, "Usage : <prog> <dbpath> <datasize>\n"); exit(1); } dbmap = dpopen(argv[1], DP_OWRITER|DP_OCREAT|DP_OSPARSE|DP_ONOLCK, -1); if (!dbmap) { fprintf(stderr, "Unable to open the dbbm file \n"); exit(1); } datap = (PDUMMY_DATA) malloc(sizeof(DUMMY_DATA)); if (!datap) { fprintf(stderr, "Malloc error %s\n", strerror(errno)); exit(1); } unsigned long datasize = strtoul(argv[2], NULL, 10); // push data for (i = 0; i < datasize; i++) { asprintf(keystr, "%s%lu", str_prefix, i); datap->x = i; datap->y = i+1; datap->z = i+2; if (!dpput(dbmap, keystr, strlen(keystr), (char *) datap, sizeof(DUMMY_DATA), DP_DOVER)) { fprintf(stderr, "Unable to insert to qdbm\n"); }; } if(!dpclose(dbmap)){ fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode)); return 1; } //read data dbmap = dpopen(argv[1], DP_OREADER, -1); if (!dbmap) { fprintf(stderr, "Unable to open the dbbm file \n"); exit(1); } fprintf(stdout, "Starting read of the database sequentially\n"); if(!dpiterinit(dbmap)){ fprintf(stderr, "dpiterinit: %s\n", dperrmsg(dpecode)); } /* scan with the iterator */ while ((key = dpiternext(dbmap, NULL)) != NULL) { if (!(datap = (PDUMMY_DATA) dpget(dbmap, key, -1, 0, sizeof(DUMMY_DATA), NULL))) { fprintf(stderr, "Value is not found for key %s\n", key); fprintf(stderr, "dpget: %s\n", dperrmsg(dpecode)); free(key); break; } /* fprintf(stdout, "Data read for dbm : x=%lu y=%lu z=%lu\n", datap->x, datap->y, datap->z);*/ free(datap); } fprintf(stdout, "End of the database reached\n"); if(!dpclose(dbmap)){ fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode)); return 1; } return 0; }