libDtSearch: Coverity 86579
[oweals/cde.git] / cde / lib / csa / rpccalls.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: rpccalls.c /main/1 1996/04/21 19:24:20 drk $ */
24 /*
25  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
26  *  (c) Copyright 1993, 1994 International Business Machines Corp.
27  *  (c) Copyright 1993, 1994 Novell, Inc.
28  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
29  */
30
31 /*****************************************************************************
32  * interface to cm rpc calls
33  * - this files make calls to v5 backend
34  * - calls to v4 and before are implemented in table.c
35  *****************************************************************************/
36
37 #include <EUSCompat.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <netdb.h>              /* define MAXHOSTNAMELEN */
42 #include <sys/utsname.h>        /* SYS_NMLN */
43 #include <unistd.h>
44 #ifdef SunOS
45 #include <sys/systeminfo.h>
46 #endif
47 #include "debug.h"
48 #include "rtable4.h" 
49 #include "cm.h"
50 #include "attr.h"
51 #include "connection.h"
52 #include "convert5-4.h"
53 #include "convert4-5.h"
54 #include "rpccalls.h"
55 #include "table.h"
56 #include "agent.h"
57 #include "cmcb.h"
58 #include "cmsdata.h"
59 #include "iso8601.h"
60 #include "misc.h"
61 #include "updateattrs.h"
62 #include "free.h"
63 #include "lutil.h"
64 #include "laccess.h"
65 #include "match.h"
66
67 extern u_long   _DtCm_transient;
68
69 static char *nullstr = "";
70
71 /*****************************************************************************
72  * forward declaration of static functions
73  *****************************************************************************/
74 static CSA_return_code csa2cmsattrs(CSA_uint32 num_attrs, CSA_attribute *csaattrs,
75                                         CSA_enum *ops, CSA_uint32 *newnum,
76                                         cms_attribute **newattrs, CSA_enum **newops);
77 static void free_cmsattrs(CSA_uint32 num_attrs, cms_attribute *attrs);
78 static CSA_return_code csa2cmsnames(CSA_uint32 num_names, char **reminder_names,
79                                         CSA_uint32 *newnum, cms_attr_name **newnames);
80 static CSA_return_code _GetV4UserAccess(Calendar *cal, cms_access_entry *alist);
81
82 /*****************************************************************************
83  * extern functions used in the library
84  *****************************************************************************/
85
86 extern CSA_return_code
87 _DtCm_rpc_open_calendar(Calendar *cal)
88 {
89         _DtCm_Client_Info       *ci=NULL;
90         CSA_return_code stat;
91
92         DP(("rpccalls.c: _DtCm_rpc_open_calendar\n"));
93
94         if (cal == NULL)
95                 return (CSA_E_INVALID_PARAMETER);
96
97         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
98             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
99                 return (stat);
100         }
101         cal->conn.ci = ci;
102         cal->conn.retry = B_TRUE;
103
104         if (ci->vers_out == TABLEVERS) {
105                 cms_open_args   arg;
106                 cms_open_res    *res;
107
108                 arg.cal = cal->name;
109                 arg.pid = getpid();
110
111                 res = cms_open_calendar_5(&arg, &cal->conn);
112
113                 if (res != NULL) {
114                         if ((stat = res->stat) == CSA_SUCCESS) {
115                                 cal->rpc_version = res->svr_vers;
116                                 cal->file_version = res->file_vers;
117                                 cal->access = res->user_access;
118                         }
119
120                         xdr_free((xdrproc_t)xdr_cms_open_res, (char *)res);
121                 } else {
122                         stat = (cal->conn.stat == RPC_SUCCESS) ?
123                                 CSA_E_SERVICE_UNAVAILABLE :
124                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
125                 }
126         } else {
127                 _DtCm_libentry          *entries;
128                 cms_access_entry        *alist;
129
130                 cal->rpc_version = ci->vers_out;
131                 cal->file_version = ci->vers_out - 1;
132  
133                 /*
134                  * call lookup_range to check the existence of
135                  * the calendar
136                  */
137                 if ((stat = _DtCm_table_lookup_range(cal, 0, 0, B_TRUE, 0, 0,
138                     0, 0, NULL, NULL, &entries)) == CSA_SUCCESS) {
139                         if (entries) _DtCm_free_libentries(entries);
140
141                         if ((stat = _DtCm_table_get_access(cal, &alist))
142                             == CSA_SUCCESS) {
143                                 stat = _GetV4UserAccess(cal, alist);
144                                 _DtCm_free_cms_access_entry(alist);
145                         }
146                 }
147         }
148         return (stat);
149 }
150
151 extern CSA_return_code
152 _DtCm_rpc_create_calendar(
153         Calendar *cal,
154         CSA_uint32 num_attrs,
155         CSA_attribute * attrs)
156 {
157         _DtCm_Client_Info       *ci=NULL;
158         CSA_return_code stat = CSA_SUCCESS;
159
160         DP(("rpccalls.c: _DtCm_rpc_create_calendar\n"));
161
162         if (cal == NULL)
163                 return (CSA_E_INVALID_PARAMETER);
164
165         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
166             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
167                 return (stat);
168         }
169         cal->conn.ci = ci;
170         cal->conn.retry = B_FALSE;
171
172         if (ci->vers_out == TABLEVERS) {
173                 cms_create_args args;
174                 CSA_return_code *res;
175                 CSA_uint32      num_cmsattrs;
176                 cms_attribute   *cmsattrs;
177
178                 if ((stat = csa2cmsattrs(num_attrs, attrs, NULL, &num_cmsattrs,
179                     &cmsattrs, NULL)) != CSA_SUCCESS)
180                         return (stat);
181
182                 args.cal        = cal->name;
183                 args.char_set   = nullstr;
184                 args.pid        = getpid();
185                 args.num_attrs  = num_cmsattrs;
186                 args.attrs      = cmsattrs;
187
188                 res = cms_create_calendar_5(&args, &cal->conn);
189
190                 if (num_cmsattrs) free_cmsattrs(num_cmsattrs, cmsattrs);
191
192                 if (res != NULL) {
193                         stat = *res;
194                 } else {
195                         stat = (cal->conn.stat == RPC_SUCCESS) ?
196                                 CSA_E_SERVICE_UNAVAILABLE :
197                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
198                 }
199         } else if (ci->vers_out == TABLEVERS_4) {
200
201                 if ((stat = _DtCm_table_create(cal))
202                     == CSA_SUCCESS && num_attrs > 0) {
203
204                         int     i;
205
206                         /*
207                          * for old backends, the only settable
208                          * calendar attribute is access list
209                          */
210                         for (i = num_attrs - 1; i >= 0; i--) {
211                                 if (attrs[i].name)
212                                         break;
213                         }
214                         if (attrs[i].value == NULL)
215                                 stat = _DtCm_table_set_access(cal, NULL);
216                         else
217                                 stat = _DtCm_table_set_access(cal,
218                                         attrs[i].value->item.access_list_value);
219                 }
220
221         } else if (ci->vers_out < TABLEVERS_4) {
222                 _DtCm_libentry          *entries;
223                 char                    *ptr, *owner;
224
225                 /* check to make sure user is not creating a calendar
226                  * using another user's name
227                  */
228                 if (ptr = strchr(cal->name, '@')) *ptr = '\0';
229                 if (_DtCmIsUserName(cal->name) == B_TRUE) {
230
231                         if ((owner = _DtCmGetUserName()) == NULL)
232                                 stat = CSA_E_FAILURE;
233
234                         if (strcmp(cal->name, owner))
235                                 stat = CSA_E_NO_AUTHORITY;
236                 } else
237                         stat = CSA_E_INVALID_PARAMETER;
238                 if (ptr) *ptr = '@';
239
240                 /*
241                  * for v2 and v3 servers, calling a lookup routine has
242                  * the side effect of having a calendar created
243                  * the calendar
244                  */
245                 if (stat == CSA_SUCCESS &&
246                     (stat = _DtCm_table_lookup_range(cal, 0, 0, B_TRUE, 0, 0,
247                     0, 0, NULL, NULL, &entries)) == CSA_SUCCESS) {
248                         if (entries) _DtCm_free_libentries(entries);
249                 }
250         }
251         return (stat);
252 }
253
254 extern CSA_return_code
255 _DtCm_rpc_delete_calendar(Calendar *cal)
256 {
257         CSA_return_code         stat;
258         _DtCm_Client_Info       *ci;
259
260         DP(("rpccalls.c: _DtCm_rpc_delete_calendar\n"));
261
262         if (cal == NULL)
263                 return (CSA_E_INVALID_PARAMETER);
264
265         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
266             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
267                 return (stat);
268         }
269
270         cal->conn.ci = ci;
271         cal->conn.retry = B_FALSE;
272
273         if (ci->vers_out == TABLEVERS) {
274                 cms_remove_args arg;
275                 CSA_return_code *res;
276
277                 arg.cal = cal->name;
278                 arg.pid = getpid();
279
280                 res = cms_remove_calendar_5(&arg, &cal->conn);
281
282                 if (res != NULL) {
283                         stat = *res;
284                 } else {
285                         stat = (cal->conn.stat == RPC_SUCCESS) ?
286                                 CSA_E_SERVICE_UNAVAILABLE :
287                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
288                 }
289         } else
290                 stat = CSA_E_NOT_SUPPORTED;
291
292         return (stat);
293 }
294
295 extern CSA_return_code
296 _DtCm_rpc_register_client(Calendar *cal, unsigned long update_type)
297 {
298         CSA_return_code stat;
299         _DtCm_Client_Info *ci = NULL;
300
301         DP(("rpccalls.c: _DtCm_rpc_register_client\n"));
302
303         if (cal == NULL)
304                 return (CSA_E_INVALID_PARAMETER);
305
306         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
307             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
308                 return (stat);
309         }
310
311         cal->conn.ci = ci;
312         cal->conn.retry = B_TRUE;
313
314         return (_DtCm_do_registration(&cal->conn, cal->name, update_type));
315 }
316
317 extern CSA_return_code
318 _DtCm_rpc_unregister_client(Calendar *cal, unsigned long update_type)
319 {
320         CSA_return_code stat;
321         _DtCm_Client_Info *ci = NULL;
322
323         DP(("rpccalls.c: _DtCm_rpc_unregister_client\n"));
324
325         if (cal == NULL)
326                 return (CSA_E_INVALID_PARAMETER);
327
328         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
329             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
330                 return (stat);
331         }
332
333         cal->conn.ci = ci;
334         cal->conn.retry = B_TRUE;
335
336         return (_DtCm_do_unregistration(&cal->conn, cal->name, update_type));
337 }
338
339 extern CSA_return_code
340 _DtCm_rpc_lookup_reminder(
341         Calendar *cal,
342         time_t tick,
343         CSA_uint32 num_names,
344         char **reminder_names,
345         CSA_uint32 *num_rems,
346         CSA_reminder_reference **rems)
347 {
348         _DtCm_Client_Info       *ci=NULL;
349         CSA_return_code stat = CSA_SUCCESS;
350
351         DP(("rpccalls.c: _DtCm_rpc_lookup_reminder\n"));
352
353         if (cal == NULL || num_rems == 0 || rems == NULL)
354                 return (CSA_E_INVALID_PARAMETER);
355
356         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
357             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
358                 return (stat);
359         }
360         cal->conn.ci = ci;
361         cal->conn.retry = B_TRUE;
362
363         if (ci->vers_out == TABLEVERS) {
364                 cms_reminder_args       args;
365                 cms_reminder_res        *res;
366                 CSA_uint32      num_cmsnames;
367                 cms_attr_name   *cmsnames;
368
369                 if ((stat = csa2cmsnames(num_names, reminder_names,
370                     &num_cmsnames, &cmsnames)) != CSA_SUCCESS)
371                         return (stat);
372
373                 args.cal        = cal->name;
374                 args.tick       = tick;
375                 args.num_names  = num_cmsnames;
376                 args.names      = cmsnames;
377
378                 res = cms_lookup_reminder_5(&args, &cal->conn);
379
380                 if (cmsnames)
381                         free(cmsnames);
382
383                 if (res != NULL) {
384                         if ((stat = res->stat) == CSA_SUCCESS)
385                                 stat = _DtCm_cms2csa_reminder_ref(res->rems,
386                                         num_rems, rems);
387                 } else {
388                         stat = (cal->conn.stat == RPC_SUCCESS) ?
389                                 CSA_E_SERVICE_UNAVAILABLE :
390                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
391                 }
392         } else {
393  
394                 stat = _DtCm_table_lookup_reminder(cal, num_names,
395                         reminder_names, num_rems, rems);
396         }
397
398         return(stat);
399 }
400
401 /*
402  * Lookup calendar entries.
403  * If it's an old server, will try to match the attributes in the library;
404  * but if attrlist contains attributes not supported by the old backend,
405  * will just return CSA_E_UNSUPPORTED_ATTRIBUTE.
406  */
407 extern CSA_return_code
408 _DtCm_rpc_lookup_entries(
409         Calendar *cal,
410         CSA_uint32 num_attrs,
411         CSA_attribute * attrs,
412         CSA_enum *ops,
413         _DtCm_libentry **elist_r)
414 {
415         _DtCm_Client_Info       *ci=NULL;
416         CSA_return_code stat = CSA_SUCCESS;
417
418         DP(("rpccalls.c: _DtCm_rpc_lookup_entries\n"));
419
420         if (cal == NULL)
421                 return (CSA_E_INVALID_PARAMETER);
422
423         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
424             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
425                 return (stat);
426         }
427         cal->conn.ci = ci;
428         cal->conn.retry = B_TRUE;
429
430         *elist_r = NULL;
431
432         if (ci->vers_out == TABLEVERS) {
433                 cms_lookup_entries_args args;
434                 cms_entries_res         *res;
435                 CSA_uint32              num_cmsattrs;
436                 cms_attribute           *cmsattrs;
437                 CSA_enum                *newops;
438
439                 if ((stat = csa2cmsattrs(num_attrs, attrs, ops, &num_cmsattrs,
440                     &cmsattrs, &newops)) != CSA_SUCCESS)
441                         return (stat);
442
443                 args.cal = cal->name;
444                 args.char_set = nullstr;
445                 args.num_attrs = num_cmsattrs;
446                 args.attrs = cmsattrs;
447                 args.ops = newops;
448
449                 res = cms_lookup_entries_5(&args, &cal->conn);
450
451                 free_cmsattrs(num_cmsattrs, cmsattrs);
452                 if (newops) free(newops);
453
454                 if (res != NULL) {
455                         if ((stat = res->stat) == CSA_SUCCESS) {
456                                 stat = _DtCmCmsentriesToLibentries(
457                                         &cal->entry_tbl, res->entries, elist_r);
458                         }
459
460                         xdr_free((xdrproc_t)xdr_cms_entries_res, (char *)res);
461                 } else {
462                         stat = (cal->conn.stat == RPC_SUCCESS) ?
463                                 CSA_E_SERVICE_UNAVAILABLE :
464                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
465                 }
466         } else {
467                 time_t          start1, start2, end1, end2;
468                 long            id;
469                 boolean_t       no_start_time_range;
470                 boolean_t       no_end_time_range;
471                 boolean_t       no_match;
472                 CSA_uint32      hnum;
473                 cms_attribute   *hattrs;
474                 CSA_enum        *hops;
475                 cms_key         key;
476                 _DtCm_libentry  *entry;
477  
478                 /* hash the matching criteria */
479                 if ((stat = _DtCmHashCriteria(cal->entry_tbl, num_attrs, attrs,
480                     NULL, ops, &no_match, &no_start_time_range,
481                     &no_end_time_range, &start1, &start2, &end1, &end2, &id,
482                     &hnum, &hattrs, &hops)) == CSA_E_INVALID_ATTRIBUTE)
483                 {
484                         return (CSA_SUCCESS);
485                 } else if (stat != CSA_SUCCESS || no_match == B_TRUE) {
486                         return (stat);
487                 }
488
489                 if (id > 0 && no_start_time_range && no_end_time_range) {
490                         /* get the key for the first event */
491                         key.id = 0;
492                         if ((stat = _DtCm_table_lookup_key_range(cal, NULL, id,
493                             _DtCM_BOT, _DtCM_EOT, &key, NULL)) == CSA_SUCCESS &&
494                             key.id > 0) {
495
496                                 /* get the detail */
497                                 if ((stat = _DtCm_make_libentry(NULL, &entry))
498                                     == CSA_SUCCESS) {
499                                         entry->e->key = key;
500
501                                         if ((stat = _DtCm_table_lookup(cal,
502                                             entry)) == CSA_SUCCESS)
503                                                 *elist_r = entry;
504                                         else
505                                                 _DtCm_free_libentries(entry);
506                                 }
507                         }
508                 } else {
509                         stat = _DtCm_table_lookup_range(cal, start1, start2,
510                                 no_end_time_range, end1, end2,
511                                 id, hnum, hattrs, hops, elist_r);
512                 }
513
514                 _DtCmFreeHashedArrays(hnum, hattrs, hops);
515         }
516
517         return(stat);
518 }
519
520 extern CSA_return_code
521 _DtCm_rpc_enumerate_sequence(
522         Calendar *cal,
523         _DtCm_libentry *entry,
524         time_t start,
525         time_t end,
526         _DtCm_libentry **elist_r)
527 {
528         _DtCm_Client_Info       *ci=NULL;
529         CSA_return_code stat = CSA_SUCCESS;
530
531         DP(("rpccalls.c: _DtCm_rpc_enumerate_sequence\n"));
532
533         if (cal == NULL)
534                 return (CSA_E_INVALID_PARAMETER);
535
536         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
537             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
538                 return (stat);
539         }
540         cal->conn.ci = ci;
541         cal->conn.retry = B_TRUE;
542
543         *elist_r = NULL;
544
545         if (ci->vers_out == TABLEVERS) {
546                 cms_enumerate_args      args;
547                 cms_entries_res         *res;
548
549                 args.cal = cal->name;
550                 args.id = entry->e->key.id;
551                 args.start = start;
552                 args.end = end;
553
554                 res = cms_enumerate_sequence_5(&args, &cal->conn);
555
556                 if (res != NULL) {
557                         if ((stat = res->stat) == CSA_SUCCESS) {
558                                 stat = _DtCmCmsentriesToLibentries(
559                                         &cal->entry_tbl, res->entries, elist_r);
560                         }
561
562                         xdr_free((xdrproc_t)xdr_cms_entries_res, (char *)res);
563                 } else {
564                         stat = (cal->conn.stat == RPC_SUCCESS) ?
565                                 CSA_E_SERVICE_UNAVAILABLE :
566                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
567                 }
568
569         } else {
570  
571                 stat = _DtCm_table_lookup_key_range(cal, entry, 0, start, end,
572                         NULL, elist_r);
573         }
574
575         return(stat);
576 }
577
578 extern CSA_return_code
579 _DtCm_rpc_lookup_entry_by_id(Calendar *cal, _DtCm_libentry *entry)
580 {
581         _DtCm_Client_Info       *ci=NULL;
582         CSA_return_code stat = CSA_SUCCESS;
583
584         DP(("rpccalls.c: _DtCm_rpc_lookup_entry_by_id\n"));
585
586         if (cal == NULL)
587                 return (CSA_E_INVALID_PARAMETER);
588
589         if ((stat = _DtCm_create_tcp_client(cal->location,
590             (cal->file_version < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
591             TABLEVERS_4 : TABLEVERS), _DtCM_LONG_TIMEOUT, &ci))
592             != CSA_SUCCESS) {
593                 return (stat);
594         }
595         cal->conn.ci = ci;
596         cal->conn.retry = B_TRUE;
597
598         if (ci->vers_out == TABLEVERS) {
599                 cms_get_entry_attr_args args;
600                 cms_get_entry_attr_res  *res;
601
602                 /*
603                  * the entry reference id is filled in already
604                  * otherwise, we would not be in this routine
605                  */
606                 args.cal = cal->name;
607                 args.num_keys = 1;
608                 args.keys = &entry->e->key;
609                 args.num_names = 0;
610                 args.names = NULL;
611
612                 res = cms_get_entry_attr_5(&args, &cal->conn);
613
614                 if (res != NULL) {
615                         if (res->entries) {
616                                 if ((stat = res->entries->stat) == CSA_SUCCESS)
617                                 {
618                                         if ((stat = _DtCmUpdateAttributes(
619                                             res->entries->num_attrs,
620                                             res->entries->attrs,
621                                             &entry->e->num_attrs,
622                                             &entry->e->attrs,
623                                             &cal->entry_tbl, B_FALSE,
624                                             NULL, B_TRUE)) == CSA_SUCCESS)
625                                         {
626                                                 entry->filled = B_TRUE;
627                                         }
628                                 }
629                         } else
630                                 stat = res->stat;
631                 } else {
632                         stat = (cal->conn.stat == RPC_SUCCESS) ?
633                                 CSA_E_SERVICE_UNAVAILABLE :
634                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
635                 }
636
637                 if (res) xdr_free((xdrproc_t)xdr_cms_get_entry_attr_res, (char *)res);
638         } else {
639  
640                 stat = _DtCm_table_lookup(cal, entry);
641         }
642
643         return(stat);
644 }
645
646 extern CSA_return_code
647 _DtCm_rpc_get_cal_attrs(Calendar *cal, int index, CSA_uint32 num_names, char **names)
648 {
649         _DtCm_Client_Info       *ci;
650         CSA_return_code         stat = CSA_SUCCESS;
651         cms_attribute_value     val;
652
653         DP(("rpccalls.c: _DtCm_rpc_get_cal_attrs\n"));
654
655         if (cal == NULL)
656                 return (CSA_E_INVALID_PARAMETER);
657
658         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
659             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
660                 return (stat);
661         }
662
663         cal->conn.ci = ci;
664         cal->conn.retry = B_TRUE;
665
666         if (ci->vers_out == TABLEVERS) {
667                 cms_get_cal_attr_args   arg;
668                 cms_get_cal_attr_res    *res;
669                 CSA_uint32              num_cmsnames;
670                 cms_attr_name           *cmsnames;
671
672                 if ((stat = csa2cmsnames(num_names, names,
673                     &num_cmsnames, &cmsnames)) != CSA_SUCCESS)
674                         return (stat);
675
676                 arg.cal = cal->name;
677                 arg.num_names = num_cmsnames;
678                 arg.names = cmsnames;
679
680                 res = cms_get_calendar_attr_5(&arg, &cal->conn);
681
682                 if (res != NULL) {
683                         if ((stat = res->stat) == CSA_SUCCESS) {
684                                 if ((stat = _DtCmUpdateAttributes(
685                                     res->num_attrs, res->attrs, &cal->num_attrs,
686                                     &cal->attrs, &cal->cal_tbl, B_TRUE, NULL,
687                                     B_TRUE)) == CSA_SUCCESS)
688                                         cal->got_attrs = B_TRUE;
689                         }
690
691                         xdr_free((xdrproc_t)xdr_cms_get_cal_attr_res, (char *)res);
692                 } else {
693                         stat = (cal->conn.stat == RPC_SUCCESS) ?
694                                 CSA_E_SERVICE_UNAVAILABLE :
695                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
696                 }
697         } else {
698
699                 switch (index) {
700                 case CSA_CAL_ATTR_ACCESS_LIST_I:
701                         if ((stat = _DtCm_table_get_access(cal,
702                             &val.item.access_list_value)) == CSA_SUCCESS) {
703                                 val.type = CSA_VALUE_ACCESS_LIST;
704                                 stat = _DtCmUpdateAccessListAttrVal(&val,
705                                         &cal->attrs\
706                                         [CSA_CAL_ATTR_ACCESS_LIST_I].value);
707                                 _DtCm_free_cms_access_entry(val.item.\
708                                         access_list_value);
709                         }
710                         break;
711
712                 case CSA_CAL_ATTR_NUMBER_ENTRIES_I:
713                         if ((stat = _DtCm_table_size(cal,
714                             (int*)&val.item.uint32_value)) == CSA_SUCCESS) {
715                                 val.type = CSA_VALUE_UINT32;
716                                 stat = _DtCmUpdateSint32AttrVal(&val,
717                                         &cal->attrs\
718                                         [CSA_CAL_ATTR_NUMBER_ENTRIES_I].value);
719                         }
720                         break;
721
722                 }
723         }
724         return(stat);
725 }
726
727 extern CSA_return_code
728 _DtCm_rpc_set_cal_attrs(Calendar *cal, CSA_uint32 num_attrs, CSA_attribute * attrs)
729 {
730         _DtCm_Client_Info       *ci;
731         CSA_return_code stat = CSA_SUCCESS;
732
733         DP(("rpccalls.c: _DtCm_rpc_set_cal_attrs\n"));
734
735         if (cal == NULL || attrs == NULL)
736                 return (CSA_E_INVALID_PARAMETER);
737
738         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
739             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS)
740         {
741                 return (stat);
742         }
743
744         cal->conn.ci = ci;
745         cal->conn.retry = B_FALSE;
746
747         if (ci->vers_out == TABLEVERS) {
748                 CSA_return_code         *res;
749                 cms_set_cal_attr_args   args;
750                 CSA_uint32      num_cmsattrs;
751                 cms_attribute   *cmsattrs;
752
753                 if ((stat = csa2cmsattrs(num_attrs, attrs, NULL, &num_cmsattrs,
754                     &cmsattrs, NULL)) != CSA_SUCCESS)
755                         return (stat);
756
757                 if (num_cmsattrs == 0)
758                         return (CSA_E_INVALID_PARAMETER);
759
760                 args.cal = cal->name;
761                 args.pid = getpid();
762                 args.num_attrs = num_cmsattrs;
763                 args.attrs = cmsattrs;
764
765                 res = cms_set_calendar_attr_5(&args, &cal->conn);
766
767                 free_cmsattrs(num_cmsattrs, cmsattrs);
768
769                 if (res != NULL) {
770                         stat = *res;
771                         if (stat == CSA_SUCCESS) {
772                                 _DtCm_free_cms_attribute_values(cal->num_attrs,
773                                         cal->attrs);
774                         }
775                 } else {
776                         stat = (cal->conn.stat == RPC_SUCCESS) ?
777                                 CSA_E_SERVICE_UNAVAILABLE :
778                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
779                 }
780
781         } else {
782                 int     i;
783
784                 /*
785                  * CSA_CAL_ATTR_ACCESS_LIST is the only settable attribute
786                  */
787                 for (i = num_attrs - 1; i >= 0; i--) {
788                         if (attrs[i].name)
789                                 break;
790                 }
791                 if (attrs[i].value == NULL)
792                         stat = _DtCm_table_set_access(cal, NULL);
793                 else
794                         stat = _DtCm_table_set_access(cal,
795                                 attrs[i].value->item.access_list_value);
796         }
797
798         return (stat);
799 }
800
801 extern CSA_return_code
802 _DtCm_rpc_insert_entry(
803         Calendar *cal,
804         CSA_uint32 num_attrs,
805         CSA_attribute * attrs,
806         _DtCm_libentry **entry_r)
807 {
808         _DtCm_Client_Info       *ci = NULL;
809         CSA_return_code         stat = CSA_SUCCESS;
810
811         DP(("rpccalls.c: _DtCm_rpc_insert_entry;\n"));
812
813         if (cal == NULL || num_attrs == 0 || attrs == NULL || entry_r == NULL)
814                 return (CSA_E_INVALID_PARAMETER);
815
816         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
817             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS)
818         {
819                 return (stat);
820         }
821         cal->conn.ci = ci;
822         cal->conn.retry = B_FALSE;
823
824         if (ci->vers_out == TABLEVERS) {
825                 cms_entry_res   *res;
826                 cms_insert_args args;
827                 CSA_uint32      num_cmsattrs;
828                 cms_attribute   *cmsattrs;
829
830                 if ((stat = csa2cmsattrs(num_attrs, attrs, NULL, &num_cmsattrs,
831                     &cmsattrs, NULL)) != CSA_SUCCESS)
832                         return (stat);
833
834                 if (num_cmsattrs == 0)
835                         return (CSA_E_INVALID_PARAMETER);
836
837                 args.cal = cal->name;
838                 args.pid = getpid();
839                 args.num_attrs = num_cmsattrs;
840                 args.attrs = cmsattrs;
841
842                 res = cms_insert_entry_5(&args, &cal->conn);
843
844                 free_cmsattrs(num_cmsattrs, cmsattrs);
845
846                 if (res != NULL) {
847                         if ((stat = res->stat) == CSA_SUCCESS) {
848                                 stat = _DtCmCmsentriesToLibentries(
849                                         &cal->entry_tbl, res->entry, entry_r);
850                         }
851
852                         xdr_free((xdrproc_t)xdr_cms_entry_res, (char *)res);
853                 } else {
854                         stat = (cal->conn.stat == RPC_SUCCESS) ?
855                                 CSA_E_SERVICE_UNAVAILABLE :
856                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
857                 }
858
859         } else {
860  
861                 stat = _DtCm_table_insert(cal, num_attrs, attrs, entry_r);
862         }
863
864         return(stat);
865 }
866
867 extern CSA_return_code
868 _DtCm_rpc_update_entry(
869         Calendar *cal,
870         _DtCm_libentry *oentry,
871         CSA_uint32 num_attrs,
872         CSA_attribute * attrs,
873         CSA_enum scope,
874         _DtCm_libentry **nentry)
875 {
876         _DtCm_Client_Info       *ci = NULL;
877         CSA_return_code stat = CSA_SUCCESS;
878
879         DP(("rpccalls.c: _DtCm_rpc_update_entry\n"));
880
881         if (cal == NULL || oentry == NULL)
882                 return (CSA_E_INVALID_PARAMETER);
883
884         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
885             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS)
886         {
887                 return (stat);
888         }
889         cal->conn.ci = ci;
890         cal->conn.retry = B_FALSE;
891
892         if (ci->vers_out == TABLEVERS) {
893                 cms_entry_res   *res;
894                 cms_update_args args;
895                 CSA_uint32      num_cmsattrs;
896                 cms_attribute   *cmsattrs;
897
898                 if ((stat = csa2cmsattrs(num_attrs, attrs, NULL, &num_cmsattrs,
899                     &cmsattrs, NULL)) != CSA_SUCCESS)
900                         return (stat);
901
902                 if (num_cmsattrs == 0)
903                         return (CSA_E_INVALID_PARAMETER);
904
905                 args.cal = cal->name;
906                 args.pid = getpid();
907                 args.entry = oentry->e->key;
908                 args.scope = scope;
909                 args.num_attrs = num_cmsattrs;
910                 args.attrs = cmsattrs;
911
912                 res = cms_update_entry_5(&args, &cal->conn);
913
914                 free_cmsattrs(num_cmsattrs, cmsattrs);
915
916                 if (res != NULL) {
917                         if ((stat = res->stat) == CSA_SUCCESS) {
918                                 stat = _DtCmCmsentriesToLibentries(
919                                         &cal->entry_tbl, res->entry, nentry);
920                         }
921
922                         xdr_free((xdrproc_t)xdr_cms_entry_res, (char *)res);
923                 } else {
924                         stat = (cal->conn.stat == RPC_SUCCESS) ?
925                                 CSA_E_SERVICE_UNAVAILABLE :
926                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
927                 }
928
929         } else {
930  
931                 stat = _DtCm_table_update(cal, oentry, num_attrs, attrs,
932                                 scope, nentry);
933         }
934
935         return(stat);
936
937 }
938
939 extern CSA_return_code
940 _DtCm_rpc_delete_entry(
941         Calendar *cal,
942         _DtCm_libentry *entry,
943         CSA_enum scope)
944 {
945         _DtCm_Client_Info       *ci = NULL;
946         CSA_return_code stat = CSA_SUCCESS;
947
948         DP(("rpccalls.c: _DtCm_rpc_delete_entry\n"));
949
950         if (cal == NULL || entry == NULL)
951                 return (CSA_E_INVALID_PARAMETER);
952
953         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
954             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS)
955         {
956                 return (stat);
957         }
958         cal->conn.ci = ci;
959         cal->conn.retry = B_FALSE;
960
961         if (ci->vers_out == TABLEVERS) {
962                 CSA_return_code *res;
963                 cms_delete_args args;
964
965                 args.cal = cal->name;
966                 args.pid = getpid();
967                 args.entry = entry->e->key;
968                 args.scope = scope;
969
970                 res = cms_delete_entry_5(&args, &cal->conn);
971
972                 if (res != NULL) {
973                         stat = *res;
974                 } else {
975                         stat = (cal->conn.stat == RPC_SUCCESS) ?
976                                 CSA_E_SERVICE_UNAVAILABLE :
977                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
978                 }
979
980         } else {
981  
982                 stat = _DtCm_table_delete(cal, entry, scope);
983         }
984
985         return(stat);
986 }
987
988 extern CSA_return_code
989 _DtCm_rpc_list_calendar_attributes(
990         Calendar        *cal,
991         CSA_uint32      *number_names,
992         char            ***names_r)
993 {
994         _DtCm_Client_Info       *ci = NULL;
995         CSA_return_code stat = CSA_SUCCESS;
996
997         DP(("rpccalls.c: _DtCm_rpc_list_calendar_attributes\n"));
998
999         if (cal == NULL)
1000                 return (CSA_E_INVALID_PARAMETER);
1001
1002         if ((stat = _DtCm_create_tcp_client(cal->location, TABLEVERS,
1003             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
1004                 return (stat);
1005         }
1006         cal->conn.ci = ci;
1007         cal->conn.retry = B_TRUE;
1008
1009         if (ci->vers_out == TABLEVERS) {
1010                 cms_enumerate_calendar_attr_res *res;
1011                 char                            **names;
1012                 int                             i;
1013
1014                 *number_names = 0;
1015                 *names_r = NULL;
1016
1017                 res = cms_enumerate_calendar_attr_5(&cal->name, &cal->conn);
1018
1019                 if (res != NULL) {
1020                         if ((stat = res->stat) == CSA_SUCCESS && res->num_names)
1021                         {
1022                                 if (names = _DtCm_alloc_character_pointers(
1023                                     res->num_names)) {
1024                                         for (i = 0; i < res->num_names; i++) {
1025                                                 if ((names[i] = strdup(
1026                                                     res->names[i].name))
1027                                                     == NULL) {
1028                                                         _DtCm_free(names);
1029                                                         return (CSA_E_INSUFFICIENT_MEMORY);
1030                                                 }
1031                                         }
1032                                         *number_names = res->num_names;
1033                                         *names_r = names;
1034                                 }
1035                         }
1036                 } else {
1037                         stat = (cal->conn.stat == RPC_SUCCESS) ?
1038                                 CSA_E_SERVICE_UNAVAILABLE :
1039                                 _DtCm_clntstat_to_csastat(cal->conn.stat);
1040                 }
1041
1042         } else {
1043  
1044                 stat = CSA_E_NOT_SUPPORTED;
1045         }
1046
1047         return(stat);
1048 }
1049
1050 extern CSA_return_code
1051 _DtCm_rpc_list_calendars(
1052         char                    *location,
1053         CSA_uint32              *number_names,
1054         CSA_calendar_user       **names_r)
1055 {
1056         _DtCm_Client_Info       *ci = NULL;
1057         CSA_return_code stat = CSA_SUCCESS;
1058         _DtCm_Connection        conn;
1059
1060         DP(("rpccalls.c: _DtCm_rpc_list_calendars\n"));
1061
1062         if ((stat = _DtCm_create_tcp_client(location, TABLEVERS,
1063             _DtCM_LONG_TIMEOUT, &ci)) != CSA_SUCCESS) {
1064                 return (stat);
1065         }
1066         conn.ci = ci;
1067         conn.retry = B_TRUE;
1068
1069         if (ci->vers_out == TABLEVERS) {
1070                 cms_list_calendars_res  *res;
1071                 CSA_calendar_user       *names;
1072                 int                     i;
1073
1074                 *number_names = 0;
1075                 *names_r = NULL;
1076
1077                 res = cms_list_calendars_5(NULL, &conn);
1078
1079                 if (res != NULL) {
1080                         if ((stat = res->stat) == CSA_SUCCESS && res->num_names)
1081                         {
1082                                 if (names = _DtCm_alloc_calendar_users(
1083                                     res->num_names)) {
1084                                         for (i = 0; i < res->num_names; i++) {
1085                                                 if ((names[i].calendar_address =
1086                                                     strdup(res->names[i]))
1087                                                     == NULL) {
1088                                                         _DtCm_free(names);
1089                                                         return (CSA_E_INSUFFICIENT_MEMORY);
1090                                                 }
1091                                         }
1092                                         *number_names = res->num_names;
1093                                         *names_r = names;
1094                                 }
1095                         }
1096                 } else {
1097                         stat = (conn.stat == RPC_SUCCESS) ?
1098                                 CSA_E_SERVICE_UNAVAILABLE :
1099                                 _DtCm_clntstat_to_csastat(conn.stat);
1100                 }
1101
1102         } else {
1103  
1104                 stat = CSA_E_NOT_SUPPORTED;
1105         }
1106
1107         return(stat);
1108 }
1109
1110 extern CSA_return_code
1111 _DtCm_do_unregistration(
1112         _DtCm_Connection *conn,
1113         char *cal,
1114         unsigned long update_type)
1115 {
1116         CSA_return_code stat;
1117
1118         if (conn->ci->vers_out == TABLEVERS) {
1119                 cms_register_args args;
1120                 CSA_return_code *res;
1121
1122                 args.cal = cal;
1123                 args.update_type = update_type;
1124                 args.prognum = _DtCm_transient;
1125                 args.versnum = AGENTVERS_2;
1126                 args.procnum = update_callback;
1127                 args.pid = getpid();
1128
1129                 res = cms_unregister_5(&args, conn);
1130
1131                 if (res != NULL) {
1132                         stat = *res;
1133                 } else {
1134                         stat = (conn->stat == RPC_SUCCESS) ?
1135                                 CSA_E_SERVICE_UNAVAILABLE :
1136                                 _DtCm_clntstat_to_csastat(conn->stat);
1137                 }
1138         } else {
1139                 stat = _DtCm_table_unregister_target(conn, cal);
1140         }
1141
1142         if (stat == CSA_SUCCESS)
1143                 _DtCm_remove_registration(conn->ci, cal);
1144
1145         return (stat);
1146 }
1147
1148 extern CSA_return_code
1149 _DtCm_do_registration(
1150         _DtCm_Connection *conn,
1151         char *cal,
1152         unsigned long update_type)
1153 {
1154         CSA_return_code stat;
1155
1156         if (conn->ci->vers_out == TABLEVERS) {
1157                 cms_register_args args;
1158                 CSA_return_code *res;
1159
1160                 args.cal = cal;
1161                 args.update_type = update_type;
1162                 args.prognum = _DtCm_transient;
1163                 args.versnum = AGENTVERS_2;
1164                 args.procnum = update_callback;
1165                 args.pid = getpid();
1166
1167                 res = cms_register_5(&args, conn);
1168
1169                 if (res != NULL)
1170                         stat = *res;
1171                 else {
1172                         stat = (conn->stat == RPC_SUCCESS) ?
1173                                 CSA_E_SERVICE_UNAVAILABLE :
1174                                 _DtCm_clntstat_to_csastat(conn->stat);
1175                 }
1176         } else {
1177
1178                 stat = _DtCm_table_register_target(conn, cal);
1179         }
1180
1181         if (stat == CSA_SUCCESS) {
1182                 if ((stat = _DtCm_add_registration(conn->ci, cal, update_type))
1183                     != CSA_SUCCESS) {
1184                         (void) _DtCm_do_unregistration(conn, cal, update_type);
1185                 }
1186         }
1187
1188         return (stat);
1189 }
1190
1191 /*****************************************************************************
1192  * static functions used within the file
1193  *****************************************************************************/
1194
1195 /*
1196  * Newnum is initialized to 0 and newattrs to NULL when num_attrs == 0
1197  */
1198 static CSA_return_code
1199 csa2cmsattrs(
1200         CSA_uint32      num_attrs,
1201         CSA_attribute   *csaattrs,
1202         CSA_enum        *ops,
1203         CSA_uint32      *newnum,
1204         cms_attribute   **newattrs,
1205         CSA_enum        **newops)
1206 {
1207         CSA_return_code stat = CSA_SUCCESS;
1208         cms_attribute   *cmsattrs;
1209         CSA_enum        *ops_r;
1210         CSA_reminder    *rptr1, *rptr2;
1211         int             i,j;
1212
1213         *newnum = 0;
1214         *newattrs = NULL;
1215         if (newops) *newops = NULL;
1216
1217         if (num_attrs == 0)
1218                 return CSA_SUCCESS;
1219
1220         if ((cmsattrs = calloc(1, sizeof(cms_attribute)*num_attrs)) == NULL)
1221                 return (CSA_E_INSUFFICIENT_MEMORY);
1222
1223         if (newops && (ops_r = malloc(sizeof(CSA_enum)*num_attrs)) == NULL) {
1224                 free(cmsattrs);
1225                 return (CSA_E_INSUFFICIENT_MEMORY);
1226         }
1227
1228         for (i = 0, j = 0; i < num_attrs && stat == CSA_SUCCESS; i++) {
1229                 if (csaattrs[i].name == NULL)
1230                         continue;
1231
1232                 if (newops)
1233                         ops_r[j] = (ops ? ops[i] : CSA_MATCH_EQUAL_TO);
1234
1235                 cmsattrs[j].name.name = csaattrs[i].name;
1236                 if (csaattrs[i].value == NULL) {
1237                         j++;
1238                         continue;
1239                 }
1240
1241                 if ((cmsattrs[j].value = (cms_attribute_value *)malloc(
1242                     sizeof(cms_attribute_value))) == NULL) {
1243                         stat = CSA_E_INSUFFICIENT_MEMORY;
1244                         break;
1245                 }
1246
1247                 cmsattrs[j].value->type = csaattrs[i].value->type;
1248
1249                 switch (csaattrs[i].value->type) {
1250                 case CSA_VALUE_ACCESS_LIST:
1251                         stat = _DtCm_csa2cms_access_list(
1252                                 csaattrs[i].value->item.access_list_value,
1253                                 &cmsattrs[j].value->item.access_list_value);
1254                         break;
1255                 case CSA_VALUE_CALENDAR_USER:
1256                         if (csaattrs[i].value->item.calendar_user_value &&
1257                             csaattrs[i].value->item.calendar_user_value->\
1258                             user_name)
1259                         {
1260                                 cmsattrs[j].value->item.calendar_user_value =
1261                                         csaattrs[i].value->item.\
1262                                         calendar_user_value->user_name;
1263                         } else {
1264                                 cmsattrs[j].value->item.calendar_user_value =
1265                                         nullstr;
1266                         }
1267                         break;
1268                 case CSA_VALUE_STRING:
1269                 case CSA_VALUE_DATE_TIME:
1270                 case CSA_VALUE_DATE_TIME_RANGE:
1271                 case CSA_VALUE_TIME_DURATION:
1272                         if (csaattrs[i].value->item.string_value) {
1273                                 cmsattrs[j].value->item.string_value =
1274                                         csaattrs[i].value->item.string_value;
1275                         } else {
1276                                 cmsattrs[j].value->item.string_value = nullstr;
1277                         }
1278                         break;
1279                 case CSA_VALUE_REMINDER:
1280                         if ((rptr1 = csaattrs[i].value->item.reminder_value) &&
1281                             (rptr2 = (CSA_reminder *)malloc(sizeof(CSA_reminder))))
1282                         {
1283                                 rptr2->lead_time = rptr1->lead_time ?
1284                                                     rptr1->lead_time : nullstr;
1285                                 rptr2->snooze_time = rptr1->snooze_time ?
1286                                                      rptr1->snooze_time:nullstr;
1287                                 rptr2->repeat_count = rptr1->repeat_count;
1288                                 rptr2->reminder_data = rptr1->reminder_data;
1289                                 cmsattrs[j].value->item.reminder_value = rptr2;
1290                         } else if (rptr1 && rptr2 == NULL)
1291                                 stat = CSA_E_INSUFFICIENT_MEMORY;
1292                         break;
1293                 default:
1294                         /* all other value types uses the same type
1295                          * of data, so we just copy the value/address of
1296                          * of the data
1297                          */
1298                         cmsattrs[j].value->item.sint32_value =
1299                                 csaattrs[i].value->item.sint32_value;
1300                 }
1301                 j++;
1302         }
1303
1304         if (stat != CSA_SUCCESS) {
1305
1306                 free_cmsattrs(num_attrs, cmsattrs);
1307                 if (newops) free(ops_r);
1308
1309         } else if (j > 0) {
1310                 *newnum = j;
1311                 *newattrs = cmsattrs;
1312                 if (newops) *newops = ops_r;
1313         } else {
1314                 free(cmsattrs);
1315                 if (newops) free(ops_r);
1316         }
1317
1318         return (stat);
1319 }
1320
1321 static void
1322 free_cmsattrs(CSA_uint32 num_attrs, cms_attribute *attrs)
1323 {
1324         int i;
1325
1326         for (i = 0; i < num_attrs; i++) {
1327                 if (attrs[i].value == NULL)
1328                         continue;
1329
1330                 switch (attrs[i].value->type) {
1331                 case CSA_VALUE_ACCESS_LIST:
1332                         _DtCm_free_cms_access_entry(
1333                                 attrs[i].value->item.access_list_value);
1334                         break;
1335                 case CSA_VALUE_REMINDER:
1336                         if (attrs[i].value->item.reminder_value)
1337                                 free(attrs[i].value->item.reminder_value);
1338                         break;
1339                 }
1340
1341                 free(attrs[i].value);
1342         }
1343         free (attrs);
1344 }
1345
1346 /*
1347  * Newnum is initialized to 0 and newattrs to NULL when num_attrs == 0
1348  */
1349 static CSA_return_code
1350 csa2cmsnames(
1351         CSA_uint32      num_names,
1352         char            **reminder_names,
1353         CSA_uint32      *newnum,
1354         cms_attr_name   **newnames)
1355 {
1356         cms_attr_name   *cmsnames;
1357         int             i,j;
1358
1359         *newnum = 0;
1360         *newnames = NULL;
1361
1362         if (num_names == 0)
1363                 return (CSA_SUCCESS);
1364
1365         if ((cmsnames = calloc(1, sizeof(cms_attr_name)*num_names)) == NULL)
1366                 return (CSA_E_INSUFFICIENT_MEMORY);
1367
1368         for (i = 0, j = 0; i < num_names; i++) {
1369                 if (reminder_names[i] == NULL)
1370                         continue;
1371                 else {
1372                         cmsnames[j].name = reminder_names[i];
1373                         j++;
1374                 }
1375         }
1376
1377         if (j > 0) {
1378                 *newnum = j;
1379                 *newnames = cmsnames;
1380         } else
1381                 free(cmsnames);
1382
1383         return (CSA_SUCCESS);
1384 }
1385
1386 /*
1387  * It is an old server and so we need to determine whether the user
1388  * is the calendar owner ourselves.
1389  * If the calendar name is the same as a user name, then that user
1390  * is the owner, and we just need to make sure the calendar is located
1391  * in the same domain as ours.  If the calendar is located in another
1392  * domain and since we can't do cross domain authentication yet, to be save
1393  * we assume that the user is not the owner.
1394  * If the calendar name is not a user name, we need to make an rpc call
1395  * (table_set_access) to test whether the user is the owner.
1396  */
1397 static CSA_return_code
1398 _GetV4UserAccess(Calendar *cal, cms_access_entry *alist)
1399 {
1400         CSA_return_code stat = CSA_SUCCESS;
1401         char    *user = _DtCmGetUserName();
1402         char    *localhost = _DtCmGetHostAtDomain();
1403         char    buf[BUFSIZ];
1404         char    *ptr, *dom;
1405         int     worldaccess = 0, useraccess = 0;
1406         boolean_t isowner = B_FALSE;
1407
1408         /* first check if user is owner */
1409         if (ptr = strchr(cal->name, '@')) *ptr = '\0';
1410
1411         if (_DtCmIsUserName(cal->name) == B_TRUE) {
1412                 if (strcmp(user, cal->name) == 0) {
1413                         /* check whether calendar location is in
1414                          * the same domain
1415                          */
1416                         if (dom = strchr(cal->location, '.')) dom++;
1417                         if (dom == NULL || _DtCmIsSamePath(
1418                             _DtCmGetLocalDomain(NULL), dom) == B_TRUE)
1419                                 isowner = B_TRUE;
1420                 }
1421         } else {
1422                 CSA_access_rights       *csalist;
1423
1424                 /* need to test whether the user is the owner */
1425                 if ((stat = _DtCm_cms2csa_access_list(alist, &csalist))
1426                     == CSA_SUCCESS) {
1427
1428                         stat = _DtCm_table_set_access(cal, csalist);
1429                         _DtCm_free_csa_access_list(csalist);
1430
1431                         if (stat == CSA_SUCCESS)
1432                                 isowner = B_TRUE;
1433                         else if (stat == CSA_E_NO_AUTHORITY) {
1434                                 isowner = B_FALSE;
1435                                 stat = CSA_SUCCESS;
1436                         }
1437                 }
1438         }
1439         if (ptr) *ptr = '@';
1440         if (stat != CSA_SUCCESS)
1441                 return (stat);
1442
1443         if (isowner) {
1444                 cal->access = CSA_OWNER_RIGHTS;
1445                 return (CSA_SUCCESS);
1446         }
1447
1448         snprintf(buf, sizeof buf, "%s@%s", user, localhost);
1449         for (; alist != NULL; alist = alist->next) {
1450                 if (strcasecmp(alist->user, "world") == 0)
1451                         worldaccess = alist->rights;
1452                 else if (_DtCmIsSameUser(buf, alist->user)) {
1453                         useraccess = alist->rights;
1454                         break;
1455                 }
1456         }
1457
1458         cal->access = useraccess | worldaccess;
1459         return (CSA_SUCCESS);
1460 }
1461