nis_error nis_verifygroup (const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 50]; char leafbuf[grouplen + 2]; char domainbuf[grouplen + 2]; nis_result *res; nis_error status; char *cp, *cp2; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, 0); status = NIS_RES_STATUS (res); nis_freeresult (res); return status; } else return NIS_FAIL; }
nis_result * nis_checkpoint (const_nis_name dirname) { nis_result *res; res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (dirname != NULL) { nis_result *res2; u_int i; res2 = nis_lookup (dirname, EXPAND_NAME); if (NIS_RES_STATUS (res2) != NIS_SUCCESS) { free (res); return res2; } /* Check if obj is really a diryectory object */ if (__type_of (NIS_RES_OBJECT (res2)) != NIS_DIRECTORY_OBJ) { nis_freeresult (res2); NIS_RES_STATUS (res) = NIS_INVALIDOBJ; return res; } for (i = 0; i < NIS_RES_OBJECT (res2)->DI_data.do_servers.do_servers_len; ++i) { cp_result cpres; memset (&cpres, '\0', sizeof (cp_result)); if (__do_niscall2 (&NIS_RES_OBJECT(res2)->DI_data.do_servers.do_servers_val[i], 1, NIS_CHECKPOINT, (xdrproc_t) _xdr_nis_name, (caddr_t) &dirname, (xdrproc_t) _xdr_cp_result, (caddr_t) &cpres, 0, NULL) != NIS_SUCCESS) NIS_RES_STATUS (res) = NIS_RPCERROR; else { NIS_RES_STATUS (res) = cpres.cp_status; res->zticks += cpres.cp_zticks; res->dticks += cpres.cp_dticks; } } nis_freeresult (res2); } else NIS_RES_STATUS (res) = NIS_NOSUCHNAME; return res; }
int nisplus_init(mnt_map *m, char *map, time_t *tp) { nis_result *result; char *org; /* if map does not have ".org_dir" then append it */ nis_name map_name; int error = 0; size_t l; org = strstr(map, NISPLUS_ORGDIR); if (org == NULL) org = NISPLUS_ORGDIR; else org = ""; /* make some room for the NIS map_name */ l = strlen(map) + sizeof(NISPLUS_ORGDIR); map_name = xmalloc(l); if (map_name == NULL) { plog(XLOG_ERROR, "Unable to create map_name %s: %s", map, strerror(ENOMEM)); return ENOMEM; } xsnprintf(map_name, l, "%s%s", map, org); result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH)); /* free off the NIS map_name */ XFREE(map_name); if (result == NULL) { plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM)); return ENOMEM; } if (result->status != NIS_SUCCESS) { dlog("NISplus init <%s>: %s (%d)", map, nis_sperrno(result->status), result->status); error = ENOENT; } *tp = 0; /* no time */ nis_freeresult(result); return error; }
void nis_ping (const_nis_name dirname, unsigned int utime, const nis_object *dirobj) { nis_result *res = NULL; nis_object *obj; ping_args args; unsigned int i; if (dirname == NULL && dirobj == NULL) abort (); if (dirobj == NULL) { res = nis_lookup (dirname, MASTER_ONLY); if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS) { nis_freeresult (res); return; } obj = res->objects.objects_val; } else obj = (nis_object *) dirobj; /* Check if obj is really a diryectory object */ if (__type_of (obj) != NIS_DIRECTORY_OBJ) { nis_freeresult (res); return; } if (dirname == NULL) args.dir = obj->DI_data.do_name; else args.dir = (char *) dirname; args.stamp = utime; /* Send the ping only to replicas */ for (i = 1; i < obj->DI_data.do_servers.do_servers_len; ++i) __do_niscall2 (&obj->DI_data.do_servers.do_servers_val[i], 1, NIS_PING, (xdrproc_t) _xdr_ping_args, (caddr_t) &args, (xdrproc_t) xdr_void, (caddr_t) NULL, 0, NULL); nis_freeresult (res); }
nis_error nis_removemember (const_nis_name member, const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 14 + NIS_MAXNAMELEN]; char leafbuf[grouplen + 2]; char domainbuf[grouplen + 2]; nis_name *newmem; nis_result *res, *res2; nis_error status; char *cp, *cp2; unsigned long int i, j, k; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { cp = stpcpy (cp, "."); stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME); if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS) { if (res) { status = NIS_RES_STATUS (res); nis_freeresult (res); } else return NIS_NOMEMORY; return status; } if ((res->objects.objects_len != 1) || (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ)) { nis_freeresult (res); return NIS_INVALIDOBJ; } newmem = calloc (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len, sizeof (char *)); if (newmem == NULL) return NIS_NOMEMORY; k = NIS_RES_OBJECT (res)[0].GR_data.gr_members.gr_members_len; j = 0; for (i = 0; i < NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len; ++i) { if (strcmp (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i], member) != 0) { newmem[j] = NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i]; ++j; } else { free (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i]); --k; } } free (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val); newmem = realloc (newmem, k * sizeof (char*)); if (newmem == NULL) return NIS_NOMEMORY; NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val = newmem; NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len = k; cp = stpcpy (buf, NIS_RES_OBJECT (res)->zo_name); *cp++ = '.'; strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN); res2 = nis_modify (buf, NIS_RES_OBJECT (res)); status = NIS_RES_STATUS (res2); nis_freeresult (res); nis_freeresult (res2); return status; } else return NIS_FAIL; }
void nis_print_group_entry (const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 50]; char leafbuf[grouplen + 3]; char domainbuf[grouplen + 3]; nis_result *res; char *cp, *cp2; u_int i; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME); if (res == NULL) return; if (NIS_RES_STATUS (res) != NIS_SUCCESS || NIS_RES_NUMOBJ (res) != 1 || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ) { nis_freeresult (res); return; } char *mem_exp[NIS_RES_NUMOBJ (res)]; char *mem_imp[NIS_RES_NUMOBJ (res)]; char *mem_rec[NIS_RES_NUMOBJ (res)]; char *nomem_exp[NIS_RES_NUMOBJ (res)]; char *nomem_imp[NIS_RES_NUMOBJ (res)]; char *nomem_rec[NIS_RES_NUMOBJ (res)]; unsigned long mem_exp_cnt = 0, mem_imp_cnt = 0, mem_rec_cnt = 0; unsigned long nomem_exp_cnt = 0, nomem_imp_cnt = 0, nomem_rec_cnt = 0; for (i = 0; i < NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; ++i) { char *grmem = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i]; int neg = grmem[0] == '-'; switch (grmem[neg]) { case '*': if (neg) { nomem_imp[nomem_imp_cnt] = grmem; ++nomem_imp_cnt; } else { mem_imp[mem_imp_cnt] = grmem; ++mem_imp_cnt; } break; case '@': if (neg) { nomem_rec[nomem_rec_cnt] = grmem; ++nomem_rec_cnt; } else { mem_rec[mem_rec_cnt] = grmem; ++mem_rec_cnt; } break; default: if (neg) { nomem_exp[nomem_exp_cnt] = grmem; ++nomem_exp_cnt; } else { mem_exp[mem_exp_cnt] = grmem; ++mem_exp_cnt; } break; } } { char buf[strlen (NIS_RES_OBJECT (res)->zo_domain) + 10]; printf (_("Group entry for \"%s.%s\" group:\n"), NIS_RES_OBJECT (res)->zo_name, nis_domain_of_r (NIS_RES_OBJECT (res)->zo_domain, buf, strlen (NIS_RES_OBJECT (res)->zo_domain) + 10)); } if (mem_exp_cnt) { fputs (_(" Explicit members:\n"), stdout); for (i = 0; i < mem_exp_cnt; ++i) printf ("\t%s\n", mem_exp[i]); } else fputs (_(" No explicit members\n"), stdout); if (mem_imp_cnt) { fputs (_(" Implicit members:\n"), stdout); for (i = 0; i < mem_imp_cnt; ++i) printf ("\t%s\n", &mem_imp[i][2]); } else fputs (_(" No implicit members\n"), stdout); if (mem_rec_cnt) { fputs (_(" Recursive members:\n"), stdout); for (i = 0; i < mem_rec_cnt; ++i) printf ("\t%s\n", &mem_rec[i][1]); } else fputs (_(" No recursive members\n"), stdout); if (nomem_exp_cnt) { fputs (_(" Explicit nonmembers:\n"), stdout); for (i = 0; i < nomem_exp_cnt; ++i) printf ("\t%s\n", &nomem_exp[i][1]); } else fputs (_(" No explicit nonmembers\n"), stdout); if (nomem_imp_cnt) { fputs (_(" Implicit nonmembers:\n"), stdout); for (i = 0; i < nomem_imp_cnt; ++i) printf ("\t%s\n", &nomem_imp[i][3]); } else fputs (_(" No implicit nonmembers\n"), stdout); if (nomem_rec_cnt) { fputs (_(" Recursive nonmembers:\n"), stdout); for (i = 0; i < nomem_rec_cnt; ++i) printf ("\t%s=n", &nomem_rec[i][2]); } else fputs (_(" No recursive nonmembers\n"), stdout); nis_freeresult (res); } }
nis_error nis_addmember (const_nis_name member, const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 14 + NIS_MAXNAMELEN]; char domainbuf[grouplen + 2]; nis_result *res, *res2; nis_error status; char *cp, *cp2; cp = rawmemchr (nis_leaf_of_r (group, buf, sizeof (buf) - 1), '\0'); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME); if (NIS_RES_STATUS (res) != NIS_SUCCESS) { status = NIS_RES_STATUS (res); nis_freeresult (res); return status; } if (NIS_RES_NUMOBJ (res) != 1 || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ) { nis_freeresult (res); return NIS_INVALIDOBJ; } u_int gr_members_len = NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len; nis_name *new_gr_members_val = realloc (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val, (gr_members_len + 1) * sizeof (nis_name)); if (new_gr_members_val == NULL) goto nomem_out; NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val = new_gr_members_val; new_gr_members_val[gr_members_len] = strdup (member); if (new_gr_members_val[gr_members_len] == NULL) { nomem_out: nis_freeresult (res); return NIS_NOMEMORY; } ++NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; /* Check the buffer bounds are not exceeded. */ assert (strlen (NIS_RES_OBJECT(res)->zo_name) + 1 < grouplen + 14); cp = stpcpy (buf, NIS_RES_OBJECT(res)->zo_name); *cp++ = '.'; strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN); res2 = nis_modify (buf, NIS_RES_OBJECT (res)); status = NIS_RES_STATUS (res2); nis_freeresult (res); nis_freeresult (res2); return status; } else return NIS_FAIL; }
static int nisplus_find(void *handle, uschar *filename, uschar *query, int length, uschar **result, uschar **errmsg, uint *do_cache) { int i; int ssize = 0; int offset = 0; int error_error = FAIL; uschar *field_name = NULL; nis_result *nrt = NULL; nis_result *nre = NULL; nis_object *tno, *eno; struct entry_obj *eo; struct table_obj *ta; uschar *p = query + length; uschar *yield = NULL; do_cache = do_cache; /* Placate picky compilers */ /* Search backwards for a colon to see if a result field name has been given. */ while (p > query && p[-1] != ':') p--; if (p > query) { field_name = p; p[-1] = 0; } else p = query + length; /* Now search backwards to find the comma that starts the table name. */ while (p > query && p[-1] != ',') p--; if (p <= query) { *errmsg = US"NIS+ query malformed"; error_error = DEFER; goto NISPLUS_EXIT; } /* Look up the data for the table, in order to get the field names, check that we got back a table, and set up pointers so the field names can be scanned. */ nrt = nis_lookup(CS p, EXPAND_NAME | NO_CACHE); if (nrt->status != NIS_SUCCESS) { *errmsg = string_sprintf("NIS+ error accessing %s table: %s", p, nis_sperrno(nrt->status)); if (nrt->status != NIS_NOTFOUND && nrt->status != NIS_NOSUCHTABLE) error_error = DEFER; goto NISPLUS_EXIT; } tno = nrt->objects.objects_val; if (tno->zo_data.zo_type != TABLE_OBJ) { *errmsg = string_sprintf("NIS+ error: %s is not a table", p); goto NISPLUS_EXIT; } ta = &(tno->zo_data.objdata_u.ta_data); /* Now look up the entry in the table, check that we got precisely one object and that it is a table entry. */ nre = nis_list(CS query, EXPAND_NAME, NULL, NULL); if (nre->status != NIS_SUCCESS) { *errmsg = string_sprintf("NIS+ error accessing entry %s: %s", query, nis_sperrno(nre->status)); goto NISPLUS_EXIT; } if (nre->objects.objects_len > 1) { *errmsg = string_sprintf("NIS+ returned more than one object for %s", query); goto NISPLUS_EXIT; } else if (nre->objects.objects_len < 1) { *errmsg = string_sprintf("NIS+ returned no data for %s", query); goto NISPLUS_EXIT; } eno = nre->objects.objects_val; if (eno->zo_data.zo_type != ENTRY_OBJ) { *errmsg = string_sprintf("NIS+ error: %s is not an entry", query); goto NISPLUS_EXIT; } /* Scan the columns in the entry and in the table. If a result field was given, look for that field; otherwise concatenate all the fields with their names. */ eo = &(eno->zo_data.objdata_u.en_data); for (i = 0; i < eo->en_cols.en_cols_len; i++) { table_col *tc = ta->ta_cols.ta_cols_val + i; entry_col *ec = eo->en_cols.en_cols_val + i; int len = ec->ec_value.ec_value_len; uschar *value = US ec->ec_value.ec_value_val; /* The value may be NULL for a zero-length field. Turn this into an empty string for consistency. Remove trailing whitespace and zero bytes. */ if (value == NULL) value = US""; else while (len > 0 && (value[len-1] == 0 || isspace(value[len-1]))) len--; /* Concatenate all fields if no specific one selected */ if (field_name == NULL) { yield = string_cat(yield, &ssize, &offset,US tc->tc_name, Ustrlen(tc->tc_name)); yield = string_cat(yield, &ssize, &offset, US"=", 1); /* Quote the value if it contains spaces or is empty */ if (value[0] == 0 || Ustrchr(value, ' ') != NULL) { int j; yield = string_cat(yield, &ssize, &offset, US"\"", 1); for (j = 0; j < len; j++) { if (value[j] == '\"' || value[j] == '\\') yield = string_cat(yield, &ssize, &offset, US"\\", 1); yield = string_cat(yield, &ssize, &offset, value+j, 1); } yield = string_cat(yield, &ssize, &offset, US"\"", 1); } else yield = string_cat(yield, &ssize, &offset, value, len); yield = string_cat(yield, &ssize, &offset, US" ", 1); } /* When the specified field is found, grab its data and finish */ else if (Ustrcmp(field_name, tc->tc_name) == 0) { yield = string_copyn(value, len); goto NISPLUS_EXIT; } } /* Error if a field name was specified and we didn't find it; if no field name, ensure the concatenated data is zero-terminated. */ if (field_name != NULL) *errmsg = string_sprintf("NIS+ field %s not found for %s", field_name, query); else { yield[offset] = 0; store_reset(yield + offset + 1); } /* Restore the colon in the query, and free result store before finishing. */ NISPLUS_EXIT: if (field_name != NULL) field_name[-1] = ':'; if (nrt != NULL) nis_freeresult(nrt); if (nre != NULL) nis_freeresult(nre); if (yield != NULL) { *result = yield; return OK; } return error_error; /* FAIL or DEFER */ }
nis_error nis_addmember (const_nis_name member, const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 14 + NIS_MAXNAMELEN]; char leafbuf[grouplen + 2]; char domainbuf[grouplen + 2]; nis_result *res, *res2; nis_error status; char *cp, *cp2; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME); if (NIS_RES_STATUS (res) != NIS_SUCCESS) { status = NIS_RES_STATUS (res); nis_freeresult (res); return status; } if ((NIS_RES_NUMOBJ (res) != 1) || (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ)) { nis_freeresult (res); return NIS_INVALIDOBJ; } NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val = realloc (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val, (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len + 1) * sizeof (char *)); if (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val == NULL) goto nomem_out; NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len] = strdup (member); if (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len] == NULL) { free (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val); nomem_out: nis_freeresult (res); return NIS_NOMEMORY; } ++NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; cp = stpcpy (buf, NIS_RES_OBJECT(res)->zo_name); *cp++ = '.'; strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN); res2 = nis_modify (buf, NIS_RES_OBJECT (res)); status = NIS_RES_STATUS (res2); nis_freeresult (res); nis_freeresult (res2); return status; } else return NIS_FAIL; }
/* internal_nis_ismember () return codes: -1 principal is in -group 0 principal isn't in any group 1 pirncipal is in group */ static int internal_ismember (const_nis_name principal, const_nis_name group) { size_t grouplen = strlen (group); char buf[grouplen + 50]; char leafbuf[grouplen + 2]; char domainbuf[grouplen + 2]; nis_result *res; char *cp, *cp2; u_int i; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; strcpy (cp, cp2); } res = nis_lookup (buf, EXPAND_NAME|FOLLOW_LINKS); if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS) { nis_freeresult (res); return 0; } if ((NIS_RES_NUMOBJ (res) != 1) || (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ)) { nis_freeresult (res); return 0; } /* We search twice in the list, at first, if we have the name with a "-", then if without. "-member" has priority */ for (i = 0; i < NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len; ++i) { cp = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i]; if (cp[0] == '-') { if (strcmp (&cp[1], principal) == 0) { nis_freeresult (res); return -1; } if (cp[1] == '@') switch (internal_ismember (principal, &cp[2])) { case -1: nis_freeresult (res); return -1; case 1: nis_freeresult (res); return 1; default: break; } else if (cp[1] == '*') { char buf1[strlen (principal) + 2]; char buf2[strlen (cp) + 2]; if (strcmp (nis_domain_of_r (principal, buf1, sizeof buf1), nis_domain_of_r (cp, buf2, sizeof buf2)) == 0) { nis_freeresult (res); return -1; } } } } for (i = 0; i < NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; ++i) { cp = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i]; if (cp[0] != '-') { if (strcmp (cp, principal) == 0) { nis_freeresult (res); return 1; } if (cp[0] == '@') switch (internal_ismember (principal, &cp[1])) { case -1: nis_freeresult (res); return -1; case 1: nis_freeresult (res); return 1; default: break; } else if (cp[0] == '*') { char buf1[strlen (principal) + 2]; char buf2[strlen (cp) + 2]; if (strcmp (nis_domain_of_r (principal, buf1, sizeof buf1), nis_domain_of_r (cp, buf2, sizeof buf2)) == 0) { nis_freeresult (res); return 1; } } } } nis_freeresult (res); return 0; }