/* ----------------------------------------------------------------------- * * * nsswitch.c - module to call parser for nsswitch config and store * result into a struct. * * Copyright 2006 Ian Kent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, * USA; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include "automount.h" #include "nsswitch.h" int set_action(struct nss_action *act, char *status, char *action, int negated) { enum nsswitch_action a; if (!strcasecmp(action, "continue")) a = NSS_ACTION_CONTINUE; else if (!strcasecmp(action, "return")) a = NSS_ACTION_RETURN; else return 0; if (!strcasecmp(status, "SUCCESS")) { act[NSS_STATUS_SUCCESS].action = a; act[NSS_STATUS_SUCCESS].negated = negated; } else if (!strcasecmp(status, "NOTFOUND")) { act[NSS_STATUS_NOTFOUND].action = a; act[NSS_STATUS_NOTFOUND].negated = negated; } else if (!strcasecmp(status, "UNAVAIL")) { act[NSS_STATUS_UNAVAIL].action = a; act[NSS_STATUS_UNAVAIL].negated = negated; } else if (!strcasecmp(status, "TRYAGAIN")) { act[NSS_STATUS_TRYAGAIN].action = a; act[NSS_STATUS_TRYAGAIN].negated = negated; } else return 0; return 1; } int check_nss_result(struct nss_source *this, enum nsswitch_status result) { enum nsswitch_status status; struct nss_action a; /* Check if we have negated actions */ for (status = 0; status < NSS_STATUS_MAX; status++) { a = this->action[status]; if (a.action == NSS_ACTION_UNKNOWN) continue; if (a.negated && result != status) { if (a.action == NSS_ACTION_RETURN) { if (result == NSS_STATUS_SUCCESS) return 1; else return 0; } } } a = this->action[result]; /* Check if we have other actions for this status */ switch (result) { case NSS_STATUS_SUCCESS: if (a.action == NSS_ACTION_CONTINUE) break; return 1; case NSS_STATUS_NOTFOUND: case NSS_STATUS_UNAVAIL: case NSS_STATUS_TRYAGAIN: if (a.action == NSS_ACTION_RETURN) { return 0; } break; default: break; } return -1; } struct nss_source *add_source(struct list_head *head, char *source) { struct nss_source *s; char *tmp; enum nsswitch_status status; s = malloc(sizeof(struct nss_source)); if (!s) return NULL; memset(s, 0, sizeof(struct nss_source)); INIT_LIST_HEAD(&s->list); tmp = strdup(source); if (!tmp) { free(s); return NULL; } s->source = tmp; for (status = 0; status < NSS_STATUS_MAX; status++) s->action[status].action = NSS_ACTION_UNKNOWN; list_add_tail(&s->list, head); return s; } int free_sources(struct list_head *list) { struct nss_source *this; struct list_head *head, *next; if (list_empty(list)) return 0; head = list; next = list->next; while (next != head) { this = list_entry(next, struct nss_source, list); next = next->next; list_del(&this->list); if (this->source) free(this->source); free(this); } return 1; } /* int main(void) { struct nss_source *this; struct list_head list; struct list_head *head, *next; int status; status = nsswitch_parse(&list); if (status) { printf("error exit from nss_parse\n"); free_sources(&list); exit(1); } head = &list; next = head->next; while (next != head) { this = list_entry(next, struct nss_source, list); next = next->next; printf("list->source = %s", this->source); for (status = 0; status < NSS_STATUS_MAX; status++) { if (this->action[status].action != NSS_ACTION_UNKNOWN) printf(" ."); } printf("\n"); } free_sources(&list); exit(0); } */