]> andersk Git - moira.git/blob - server/qaccess.pc
Revert incremental code until we actually have an incremental (not yet)
[moira.git] / server / qaccess.pc
1 /* $Id$
2  *
3  * Check access to queries
4  *
5  * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6  * For copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include "mr_server.h"
12 #include "qrtn.h"
13 #include "query.h"
14
15 #include <ctype.h>
16 #include <stdlib.h>
17
18 EXEC SQL INCLUDE sqlca;
19
20 RCSID("$Header$");
21
22 extern char *whoami;
23 extern int dbms_errno, mr_errcode;
24
25 EXEC SQL WHENEVER SQLERROR DO dbmserr();
26
27
28 /* Specialized Access Routines */
29
30 /* access_user - verify that client name equals specified login name
31  *
32  *  - since field validation routines are called first, a users_id is
33  *    now in argv[0] instead of the login name.
34  */
35
36 int access_user(struct query *q, char *argv[], client *cl)
37 {
38   if (cl->users_id != *(int *)argv[0])
39     return MR_PERM;
40   else
41     return MR_SUCCESS;
42 }
43
44
45
46 /* access_login - verify that client name equals specified login name
47  *
48  *   argv[0...n] contain search info.  q->
49  */
50
51 int access_login(struct query *q, char *argv[], client *cl)
52 {
53   EXEC SQL BEGIN DECLARE SECTION;
54   int id;
55   EXEC SQL END DECLARE SECTION;
56
57   if (q->argc != 1)
58     return MR_ARGS;
59
60   if (!strcmp(q->shortname, "gual"))
61     {
62       EXEC SQL SELECT users_id INTO :id FROM users
63         WHERE login = :argv[0] AND users_id != 0;
64     }
65   else if (!strcmp(q->shortname, "gubl"))
66     {
67       EXEC SQL SELECT users_id INTO :id FROM users u
68         WHERE u.login = :argv[0] AND u.users_id != 0;
69     }
70   else if (!strcmp(q->shortname, "guau"))
71     {
72       EXEC SQL SELECT users_id INTO :id FROM users
73         WHERE unix_uid = :argv[0] AND users_id != 0;
74     }
75   else if (!strcmp(q->shortname, "gubu"))
76     {
77       EXEC SQL SELECT users_id INTO :id FROM users u
78         WHERE u.unix_uid = :argv[0] AND u.users_id != 0;
79     }
80
81   if (sqlca.sqlcode == SQL_NO_MATCH)
82     return MR_NO_MATCH; /* ought to be MR_USER, but this is what
83                            gual returns, so we have to be consistent */
84   else if (sqlca.sqlerrd[2] != 1 || id != cl->users_id)
85     return MR_PERM;
86   else
87     return MR_SUCCESS;
88 }
89
90
91 /* access_spob - check access for set_pobox */
92
93 int access_spob(struct query *q, char *argv[], client *cl)
94 {
95   EXEC SQL BEGIN DECLARE SECTION;
96   int id;
97   EXEC SQL END DECLARE SECTION;
98
99   if (!strcmp(argv[1], "IMAP"))
100       {
101         EXEC SQL SELECT owner INTO :id FROM filesys f 
102           WHERE f.label = :argv[2] AND f.type = 'IMAP' AND
103           f.lockertype = 'USER';
104         if (cl->users_id != id)
105           return MR_PERM;
106       }
107   if (cl->users_id != *(int *)argv[0])
108     return MR_PERM;
109   else
110     return MR_SUCCESS;
111 }
112
113
114 /* access_list - check access for most list operations
115  *
116  * Inputs: argv[0] - list_id
117  *          q - query name
118  *          argv[2] - member ID (only for queries "amtl" and  "dmfl")
119  *          argv[7] - group ID (only for query "ulis")
120  *          cl - client name
121  *
122  * - check that client is a member of the access control list
123  * - OR, if the query is add_member_to_list or delete_member_from_list
124  *      and the list is public, allow access if client = member
125  */
126
127 int access_list(struct query *q, char *argv[], client *cl)
128 {
129   EXEC SQL BEGIN DECLARE SECTION;
130   int list_id, acl_id, flags, gid, users_id, member_id, member_acl_id;
131   int memacl_id, mailman, mailman_id;
132   char acl_type[LIST_ACL_TYPE_SIZE], name[LIST_NAME_SIZE], *newname;
133   char member_acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
134   EXEC SQL END DECLARE SECTION;
135   int status, cnt;
136
137   list_id = *(int *)argv[0];
138   member_id = *(int *)argv[2];
139   EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type,
140     gid, publicflg, name, mailman, mailman_id
141     INTO :acl_id, :acl_type, :memacl_id, :memacl_type, 
142     :gid, :flags, :name, :mailman, :mailman_id
143     FROM list
144     WHERE list_id = :list_id;
145
146   if (sqlca.sqlerrd[2] != 1)
147     return MR_INTERNAL;
148
149   /* if update_list, don't allow them to change the GID or rename to a
150          username other than their own */
151   if (!strcmp("ulis", q->shortname))
152     {
153       if (!strcmp(argv[7], UNIQUE_GID))
154         {
155           if (gid != -1)
156             return MR_PERM;
157         }
158       else
159         {
160           if (gid != atoi(argv[7]))
161             return MR_PERM;
162         }
163
164       newname = argv[1];
165
166       /* Check that it doesn't conflict with the Grouper namespace. */
167       if (strlen(newname) > 4 && isdigit(newname[2]) && 
168           isdigit(newname[3]) && newname[4] == '-')
169         {
170           if (!strncasecmp(newname, "fa", 2) ||
171               !strncasecmp(newname, "sp", 2) ||
172               !strncasecmp(newname, "su", 2) ||
173               !strncasecmp(newname, "ja", 2))
174             return MR_RESERVED;
175         }
176       
177       /* Don't let anyone take owner-foo list names.  They interact 
178        * weirdly with the aliases automatically generated by 
179        * mailhub.gen.
180        */
181       if (!strncasecmp(newname, "owner-", 6))
182         return MR_RESERVED;
183       
184       EXEC SQL SELECT users_id INTO :users_id FROM users
185         WHERE login = :newname;
186       if ((sqlca.sqlcode != SQL_NO_MATCH) && strcmp(strtrim(name), newname) &&
187           (users_id != cl->users_id))
188         return MR_PERM;
189
190       /* For modern enough clients, don't allow ordinary users to toggle
191        * the mailman bit or change the server.
192        */
193       if (q->version >= 10)
194         {
195           if (mailman != atoi(argv[9]))
196             return MR_PERM;
197
198           if (mailman_id != *(int *)argv[10])
199             return MR_PERM;
200         }
201     }
202
203   /* check for client in access control list and return success right 
204    * away if it's there. */
205   if (find_member(acl_type, acl_id, cl))
206     return MR_SUCCESS;
207
208   /* If not amtl, atml, or dmfl, we lose. */
209   if (strcmp(q->shortname, "amtl") && strcmp(q->shortname, "atml") &&
210       strcmp(q->shortname, "dmfl") && strcmp(q->shortname, "tmol"))
211     return MR_PERM;
212
213   if (find_member(memacl_type, memacl_id, cl))
214     return MR_SUCCESS;
215
216   if (flags || q->type == DELETE)
217     {
218       if (!strcmp("USER", argv[1]) && *(int *)argv[2] == cl->users_id)
219         return MR_SUCCESS;
220       if (!strcmp("KERBEROS", argv[1]) && *(int *)argv[2] == -cl->client_id)
221         return MR_SUCCESS;
222       if (!strcmp("LIST", argv[1]) && !strcmp("dmfl", q->shortname))
223         {
224           EXEC SQL SELECT acl_id, acl_type INTO :member_acl_id, 
225             :member_acl_type 
226             FROM list
227             WHERE list_id = :member_id; 
228           
229           if (find_member(member_acl_type, member_acl_id, cl))
230             return MR_SUCCESS;
231         }
232     }
233
234   /* Otherwise fail. */
235   return MR_PERM;
236 }
237
238
239 /* access_visible_list - allow access to list only if it is not hidden,
240  *      or if the client is on the ACL
241  *
242  * Inputs: argv[0] - list_id
243  *         cl - client identifier
244  */
245
246 int access_visible_list(struct query *q, char *argv[], client *cl)
247 {
248   EXEC SQL BEGIN DECLARE SECTION;
249   int list_id, acl_id, memacl_id, flags ;
250   char acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
251   EXEC SQL END DECLARE SECTION;
252   int status;
253
254   list_id = *(int *)argv[0];
255   EXEC SQL SELECT hidden, acl_id, acl_type, memacl_id, memacl_type
256     INTO :flags, :acl_id, :acl_type, :memacl_id, :memacl_type
257     FROM list
258     WHERE list_id = :list_id;
259   if (sqlca.sqlerrd[2] != 1)
260     return MR_INTERNAL;
261   if (!flags)
262     return MR_SUCCESS;
263
264   /* check for client in access control list */
265   status = find_member(acl_type, acl_id, cl);
266   if (!status)
267     {
268       status = find_member(memacl_type, memacl_id, cl);
269       if (!status)
270         return MR_PERM;
271     }
272   return MR_SUCCESS;
273 }
274
275
276 /* access_vis_list_by_name - allow access to list only if it is not hidden,
277  *      or if the client is on the ACL
278  *
279  * Inputs: argv[0] - list name
280  *         cl - client identifier
281  */
282
283 int access_vis_list_by_name(struct query *q, char *argv[], client *cl)
284 {
285   EXEC SQL BEGIN DECLARE SECTION;
286   int acl_id, memacl_id, flags, rowcount, list_id;
287   char acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
288   char *listname;
289   EXEC SQL END DECLARE SECTION;
290   int status;
291
292   listname = argv[0];
293   EXEC SQL SELECT hidden, acl_id, acl_type, memacl_id, memacl_type, list_id 
294     INTO :flags, :acl_id, :acl_type, :memacl_id, :memacl_type, :list_id
295     FROM list 
296     WHERE name = :listname;
297
298   rowcount = sqlca.sqlerrd[2];
299   if (rowcount > 1)
300     return MR_WILDCARD;
301   if (rowcount == 0)
302     return MR_NO_MATCH;
303   if (!flags)
304     return MR_SUCCESS;
305
306   /* If the user is a member of the acl, memacl, or the list itself,
307    * accept them.
308    */
309   status = find_member(acl_type, acl_id, cl);
310   if (!status)
311     status = find_member(memacl_type, memacl_id, cl);
312   if (!status)
313     status = find_member("LIST", list_id, cl);
314   if (!status)
315     return MR_PERM;
316
317   return MR_SUCCESS;
318 }
319
320
321 /* access_member - allow user to access member of type "USER" and name matches
322  * username, or to access member of type "KERBEROS" and the principal matches
323  * the user, or to access member of type "LIST" and list is one that user is
324  * on the acl of, or the list is visible.  Allow anyone to look up list
325  * memberships of MACHINEs.
326  */
327
328 int access_member(struct query *q, char *argv[], client *cl)
329 {
330   if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
331     return access_visible_list(q, &argv[1], cl);
332
333   if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER"))
334     {
335       if (cl->users_id == *(int *)argv[1])
336         return MR_SUCCESS;
337     }
338
339   if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBEROS"))
340     {
341       if (cl->client_id == -*(int *)argv[1])
342         return MR_SUCCESS;
343     }
344
345   if (!strcmp(argv[0], "MACHINE") || !strcmp(argv[0], "RMACHINE"))
346     return MR_SUCCESS;   
347
348   return MR_PERM;
349 }
350
351
352 /* access_qgli - special access routine for Qualified_get_lists.  Allows
353  * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
354  */
355
356 int access_qgli(struct query *q, char *argv[], client *cl)
357 {
358   if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
359     return MR_SUCCESS;
360   return MR_PERM;
361 }
362
363
364 /* access_service - allow access if user is on ACL of service.  Don't
365  * allow access if a wildcard is used.
366  */
367
368 int access_service(struct query *q, char *argv[], client *cl)
369 {
370   EXEC SQL BEGIN DECLARE SECTION;
371   int acl_id;
372   char *name, acl_type[LIST_ACL_TYPE_SIZE];
373   EXEC SQL END DECLARE SECTION;
374   int status;
375   char *c;
376
377   name = argv[0];
378   for (c = name; *c; c++)
379     {
380       if (islower(*c))
381         *c = toupper(*c);
382     }
383   EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
384     WHERE name = :name;
385   if (sqlca.sqlerrd[2] > 1)
386     return MR_PERM;
387
388   /* check for client in access control list */
389   status = find_member(acl_type, acl_id, cl);
390   if (!status)
391     return MR_PERM;
392
393   return MR_SUCCESS;
394 }
395
396
397 /* access_filesys - verify that client is owner or on owners list of filesystem
398  *      named by argv[0]
399  */
400
401 int access_filesys(struct query *q, char *argv[], client *cl)
402 {
403   EXEC SQL BEGIN DECLARE SECTION;
404   int users_id, list_id;
405   char *name;
406   EXEC SQL END DECLARE SECTION;
407   int status;
408
409   name = argv[0];
410   EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
411     WHERE label = :name;
412
413   if (sqlca.sqlerrd[2] != 1)
414     return MR_PERM;
415   if (users_id == cl->users_id)
416     return MR_SUCCESS;
417   status = find_member("LIST", list_id, cl);
418   if (status)
419     return MR_SUCCESS;
420   else
421     return MR_PERM;
422 }
423
424
425 /* access_host - successful if owner of host, or subnet containing host
426  */
427
428 int access_host(struct query *q, char *argv[], client *cl)
429 {
430   EXEC SQL BEGIN DECLARE SECTION;
431   int mid, sid, id, subnet_status;
432   char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
433   char *account_number;
434   EXEC SQL END DECLARE SECTION;
435   int status, idx;
436
437   if (q->version < 6)
438     idx = 0;
439   else if (q->version >= 6 && q->version < 8)
440     idx = 1;
441   else
442     idx = 2;
443   
444   if (q->type == RETRIEVE)
445     {
446       if (strcmp(argv[0], "*") || strcmp(argv[1], "*") ||
447           strcmp(argv[2], "*") || strcmp(argv[3], "*"))
448         return MR_SUCCESS;
449       else
450         return MR_PERM;
451     }
452
453   if (q->type == APPEND)
454     {
455       /* Non-query owner must set use to zero */
456       if (atoi(argv[6 + idx]) != 0)
457         return MR_PERM;
458
459       /* ... and start the hostname with a letter */
460       if (isdigit(argv[0][0]))
461         return MR_BAD_CHAR;
462
463       id = *(int *)argv[8 + idx];
464       EXEC SQL SELECT s.owner_type, s.owner_id, s.status
465         INTO :stype, :sid, :subnet_status FROM subnet s
466         WHERE s.snet_id = :id;
467       mid = 0;
468
469       /* Non query owner must provide valid billing information. */
470       if (q->version >= 8)
471         {
472           if (subnet_status == SNET_STATUS_BILLABLE)
473             {
474               account_number = argv[7];
475               EXEC SQL SELECT account_number FROM accountnumbers 
476                 WHERE account_number = :account_number;
477               if (sqlca.sqlcode == SQL_NO_MATCH)
478                 return MR_ACCOUNT_NUMBER;
479             }
480         }
481
482       if (find_member(stype, sid, cl))
483         return MR_SUCCESS;
484       else
485         return MR_PERM;
486     }
487   else /* q-type == UPDATE */
488     {
489       EXEC SQL BEGIN DECLARE SECTION;
490       int status, acomment, use, ocomment, snid;
491       char contact[MACHINE_CONTACT_SIZE], address[MACHINE_ADDRESS_SIZE];
492       char name[MACHINE_NAME_SIZE];
493       char billing_contact[MACHINE_BILLING_CONTACT_SIZE];
494       EXEC SQL END DECLARE SECTION;
495
496       id = *(int *)argv[0];
497       EXEC SQL SELECT m.name, m.use, m.contact, m.billing_contact, m.status, 
498         m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, m.snet_id,
499         s.owner_type, s.owner_id, s.status INTO :name, :use, :contact, 
500         :billing_contact, :status, :address, :mtype, :mid, :acomment, 
501         :ocomment, :snid, :stype, :sid, :subnet_status
502         FROM machine m, subnet s
503         WHERE m.mach_id = :id AND s.snet_id = m.snet_id;
504       if (dbms_errno)
505         return mr_errcode;
506
507       /* Non query owner must provide valid billing information. */
508       if (q->version >= 8)
509         {
510           if ((subnet_status == SNET_STATUS_BILLABLE) &&
511               (atoi(argv[10]) != 3))
512             {
513               account_number = argv[8];
514               EXEC SQL SELECT account_number FROM accountnumbers 
515                 WHERE account_number = :account_number;
516               if (sqlca.sqlcode == SQL_NO_MATCH)
517                 return MR_ACCOUNT_NUMBER;
518             }
519         }
520
521       /* non-query-owner cannot change use or ocomment */
522       if ((use != atoi(argv[7 + idx])) || (ocomment != *(int *)argv[14 + idx]))
523         return MR_PERM;
524
525       /* or rename to start with digit */
526       if (isdigit(argv[1][0]) && strcmp(strtrim(name), argv[1]))
527         return MR_BAD_CHAR;
528
529       if (!find_member(stype, sid, cl))
530         {
531           if (find_member(mtype, mid, cl))
532             {
533               /* host owner also cannot change contact, status, address,
534                  owner, or acomment */
535               if (strcmp(argv[6], strtrim(contact)) ||
536                   (status != atoi(argv[8 + idx])) ||
537                   strcmp(argv[10 + idx], strtrim(address)) ||
538                   strcmp(argv[11 + idx], strtrim(mtype)) ||
539                   (mid != *(int *)argv[12 + idx]) || 
540                   (acomment != *(int *)argv[13 + idx]))
541                 return MR_PERM;
542               /* Billing contact field didn't appear until version 6 */
543               if (q->version >= 6)
544                 if (strcmp(argv[7], strtrim(billing_contact)))
545                     return MR_PERM;
546             }
547           else
548             return MR_PERM;
549         }
550
551       /* If moving to a new subnet, make sure user is on acl there */
552       id = *(int *)argv[9 + idx];
553       if (id != snid)
554         {
555           EXEC SQL SELECT owner_type, owner_id INTO :stype, :sid
556             FROM subnet WHERE snet_id=:id;
557           if (!find_member(stype, sid, cl))
558             return MR_PERM;
559         }
560
561       return MR_SUCCESS;
562     }
563 }
564
565
566 /* access_ahal - check for adding a host alias.
567  * successful if host has less then 2 aliases and (client is owner of
568  * host or subnet).
569  * If deleting an alias, any owner will do.
570  */
571
572 int access_ahal(struct query *q, char *argv[], client *cl)
573 {
574   EXEC SQL BEGIN DECLARE SECTION;
575   int cnt, id, mid, sid;
576   char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
577   EXEC SQL END DECLARE SECTION;
578   int status;
579
580   if (q->type == RETRIEVE)
581     return MR_SUCCESS;
582
583   id = *(int *)argv[1];
584
585   if (q->type == APPEND && isdigit(argv[0][0]))
586     return MR_BAD_CHAR;
587
588   EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
589   if (dbms_errno)
590     return mr_errcode;
591   /* if the type is APPEND, this is ahal and we need to make sure there
592    * will be no more than 2 aliases.  If it's not, it must be dhal and
593    * any owner will do.
594    */
595   if (q->type == APPEND && cnt >= 2)
596     return MR_PERM;
597   EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
598     INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
599     WHERE m.mach_id = :id and s.snet_id = m.snet_id;
600   status = find_member(mtype, mid, cl);
601   if (status)
602     return MR_SUCCESS;
603   status = find_member(stype, sid, cl);
604   if (status)
605     return MR_SUCCESS;
606   else
607     return MR_PERM;
608 }
609
610
611 /* access_snt - check for retrieving network structure
612  */
613
614 int access_snt(struct query *q, char *argv[], client *cl)
615 {
616   if (q->type == RETRIEVE)
617     return MR_SUCCESS;
618
619   return MR_PERM;
620 }
621
622
623 /* access_printer */
624 int access_printer(struct query *q, char *argv[], client *cl)
625 {
626   EXEC SQL BEGIN DECLARE SECTION;
627   char type[PRINTSERVERS_OWNER_TYPE_SIZE];
628   int id, mach_id;
629   EXEC SQL END DECLARE SECTION;
630   int status;
631
632   mach_id = *(int *)argv[PRN_RM];
633   EXEC SQL SELECT owner_type, owner_id INTO :type, :id
634     FROM printservers WHERE mach_id = :mach_id;
635   if (sqlca.sqlcode)
636     return MR_PERM;
637
638   status = find_member(type, id, cl);
639   if (status)
640     return MR_SUCCESS;
641   else
642     return MR_PERM;
643 }
644
645 /* access_zephyr */
646 int access_zephyr(struct query *q, char *argv[], client *cl)
647 {
648   EXEC SQL BEGIN DECLARE SECTION;
649   char type[ZEPHYR_OWNER_TYPE_SIZE];
650   char *class;
651   int id;
652   EXEC SQL END DECLARE SECTION;
653   int status;
654
655   class = argv[ZA_CLASS];
656   EXEC SQL SELECT owner_type, owner_id INTO :type, :id
657       FROM zephyr WHERE class = :class;
658   if (sqlca.sqlcode)
659     return MR_PERM;
660
661   status = find_member(type, id, cl);
662   if (status)
663     return MR_SUCCESS;
664   else
665     return MR_PERM;
666 }
667
668 /* access_container - check access for most container operations
669  *
670  * Inputs: argv[0] - cnt_id
671  *          q - query name        
672  *          cl - client name
673  *
674  * - check if that client is a member of the access control list
675  * - OR, if the query is add_machine_to_container or delete_machine_from_container
676  *      check if the client is a memeber of the mem_acl list
677  * - if the query is update_container and the container is to be renamed and
678  *   it is a top-level container, only priviledged users can do it
679  */
680
681 int access_container(struct query *q, char *argv[], client *cl)
682 {
683   EXEC SQL BEGIN DECLARE SECTION;
684   int cnt_id, acl_id, memacl_id, mach_id, machine_owner_id, flag;
685   char acl_type[CONTAINERS_ACL_TYPE_SIZE], memacl_type[CONTAINERS_ACL_TYPE_SIZE];
686   char name[CONTAINERS_NAME_SIZE], *newname;
687   char machine_owner_type[MACHINE_OWNER_TYPE_SIZE];
688   EXEC SQL END DECLARE SECTION;
689   int status;
690
691   cnt_id = *(int *)argv[0];
692   
693   /* if amcn or dmcn, container id is the second argument */
694   if (strcmp(q->shortname, "amcn") == 0 || strcmp(q->shortname, "dmcn") == 0)
695   {
696         mach_id = *(int *)argv[0];
697         cnt_id = *(int *)argv[1];
698   }
699
700   EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type, name, publicflg
701     INTO :acl_id, :acl_type, :memacl_id, :memacl_type, :name, :flag
702     FROM containers
703     WHERE cnt_id = :cnt_id;
704
705   if (sqlca.sqlerrd[2] != 1)
706     return MR_INTERNAL;
707
708    /* trim off the trailing spaces */
709    strcpy(name, strtrim(name));
710
711   /* if the query is update_container and the containers is to be renamed
712    * and it is a top-level container, only dbadmin can do it */
713   if (!strcmp(q->shortname, "ucon"))
714   {
715     newname = argv[1];
716     if (strcmp(name, newname) && strchr(name, '/') == NULL)
717       return MR_PERM;
718   }
719
720   /* check for client in access control list and return success right 
721    * away if it's there. */
722   if (find_member(acl_type, acl_id, cl))
723     return MR_SUCCESS;
724
725   /* If not amcn, dmcn, we lose. */
726   if (strcmp(q->shortname, "amcn") && strcmp(q->shortname, "dmcn"))
727     return MR_PERM;
728
729   if (find_member(memacl_type, memacl_id, cl))
730     return MR_SUCCESS;
731
732   /* if the container is public or the query is delete, grant access if client
733    * is on owner list */
734   if (flag || q->type == DELETE)
735     {
736           EXEC SQL SELECT owner_type, owner_id INTO :machine_owner_type,
737             :machine_owner_id
738             FROM machine
739             WHERE mach_id = :mach_id;
740
741           if (sqlca.sqlerrd[2] == 1 && strcmp("NONE", machine_owner_type) &&
742                 find_member(machine_owner_type, machine_owner_id, cl))
743             return MR_SUCCESS;
744     }
745   /* Otherwise fail. */
746   return MR_PERM;
747 }
This page took 0.201628 seconds and 5 git commands to generate.