s4: import lorikeet-heimdal-200810271034
[sfrench/samba-autobuild/.git] / source4 / heimdal / lib / krb5 / config_file_netinfo.c
1 /*
2  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "krb5_locl.h"
35 RCSID("$Id$");
36
37 /*
38  * Netinfo implementation from Luke Howard <lukeh@xedoc.com.au>
39  */
40
41 #ifdef HAVE_NETINFO
42 #include <netinfo/ni.h>
43 static ni_status
44 ni_proplist2binding(ni_proplist *pl, krb5_config_section **ret)
45 {
46     int i, j;
47     krb5_config_section **next = NULL;
48
49     for (i = 0; i < pl->ni_proplist_len; i++) {
50         if (!strcmp(pl->nipl_val[i].nip_name, "name"))
51             continue;
52
53         for (j = 0; j < pl->nipl_val[i].nip_val.ni_namelist_len; j++) {
54             krb5_config_binding *b;
55
56             b = malloc(sizeof(*b));
57             if (b == NULL)
58                 return NI_FAILED;
59         
60             b->next = NULL;
61             b->type = krb5_config_string;
62             b->name = ni_name_dup(pl->nipl_val[i].nip_name);
63             b->u.string = ni_name_dup(pl->nipl_val[i].nip_val.ninl_val[j]);
64
65             if (next == NULL) {
66                 *ret = b;
67             } else {
68                 *next = b;
69             }
70             next = &b->next;
71         }
72     }
73     return NI_OK;
74 }
75
76 static ni_status
77 ni_idlist2binding(void *ni, ni_idlist *idlist, krb5_config_section **ret)
78 {
79     int i;
80     ni_status nis;
81     krb5_config_section **next;
82
83     for (i = 0; i < idlist->ni_idlist_len; i++) {
84         ni_proplist pl;
85         ni_id nid;
86         ni_idlist children;
87         krb5_config_binding *b;
88         ni_index index;
89
90         nid.nii_instance = 0;
91         nid.nii_object = idlist->ni_idlist_val[i];
92
93         nis = ni_read(ni, &nid, &pl);
94
95         if (nis != NI_OK) {
96              return nis;
97         }
98         index = ni_proplist_match(pl, "name", NULL);
99         b = malloc(sizeof(*b));
100         if (b == NULL) return NI_FAILED;
101
102         if (i == 0) {
103             *ret = b;
104         } else {
105             *next = b;
106         }
107
108         b->type = krb5_config_list;
109         b->name = ni_name_dup(pl.nipl_val[index].nip_val.ninl_val[0]);
110         b->next = NULL;
111         b->u.list = NULL;
112
113         /* get the child directories */
114         nis = ni_children(ni, &nid, &children);
115         if (nis == NI_OK) {
116             nis = ni_idlist2binding(ni, &children, &b->u.list);
117             if (nis != NI_OK) {
118                 return nis;
119             }
120         }
121
122         nis = ni_proplist2binding(&pl, b->u.list == NULL ? &b->u.list : &b->u.list->next);
123         ni_proplist_free(&pl);
124         if (nis != NI_OK) {
125             return nis;
126         }
127         next = &b->next;
128     }
129     ni_idlist_free(idlist);
130     return NI_OK;
131 }
132
133 krb5_error_code KRB5_LIB_FUNCTION
134 krb5_config_parse_file (krb5_context context,
135                         const char *fname,
136                         krb5_config_section **res)
137 {
138     void *ni = NULL, *lastni = NULL;
139     int i;
140     ni_status nis;
141     ni_id nid;
142     ni_idlist children;
143
144     krb5_config_section *s;
145     int ret;
146
147     s = NULL;
148
149     for (i = 0; i < 256; i++) {
150         if (i == 0) {
151             nis = ni_open(NULL, ".", &ni);
152         } else {
153             if (lastni != NULL) ni_free(lastni);
154             lastni = ni;
155             nis = ni_open(lastni, "..", &ni);
156         }
157         if (nis != NI_OK)
158             break;
159         nis = ni_pathsearch(ni, &nid, "/locations/kerberos");
160         if (nis == NI_OK) {
161             nis = ni_children(ni, &nid, &children);
162             if (nis != NI_OK)
163                 break;
164             nis = ni_idlist2binding(ni, &children, &s);
165             break;
166         }
167     }
168
169     if (ni != NULL) ni_free(ni);
170     if (ni != lastni && lastni != NULL) ni_free(lastni);
171
172     ret = (nis == NI_OK) ? 0 : -1;
173     if (ret == 0) {
174         *res = s;
175     } else {
176         *res = NULL;
177     }
178     return ret;
179 }
180 #endif /* HAVE_NETINFO */