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