Windows global stuff:
[krb5.git] / src / lib / krb5 / ccache / stdio / scc_gennew.c
1 /*
2  * lib/krb5/ccache/stdio/scc_gennew.c
3  *
4  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  * 
23  *
24  * This file contains the source code for krb5_scc_generate_new.
25  */
26
27 #include "scc.h"
28 #include "k5-int.h"
29
30 extern krb5_cc_ops krb5_scc_ops;
31
32 /*
33  * Effects:
34  * Creates a new file cred cache whose name is guaranteed to be
35  * unique.  The name begins with the string TKT_ROOT (from scc.h).
36  * The cache is not opened, but the new filename is reserved.
37  *  
38  * Returns:
39  * The filled in krb5_ccache id.
40  *
41  * Errors:
42  * KRB5_CC_NOMEM - there was insufficient memory to allocate the
43  *              krb5_ccache.  id is undefined.
44  * system errors (from open)
45  */
46 krb5_error_code
47 krb5_scc_generate_new (context, id)
48    krb5_context context;
49    krb5_ccache *id;
50 {
51      krb5_ccache lid;
52      FILE *f;
53      krb5_error_code    retcode = 0;
54      char scratch[sizeof(TKT_ROOT)+6+1]; /* +6 for the scratch part, +1 for
55                                             NUL */
56      
57      /* Allocate memory */
58      lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
59      if (lid == NULL)
60           return KRB5_CC_NOMEM;
61
62      lid->ops = &krb5_scc_ops;
63
64      (void) strcpy(scratch, TKT_ROOT);
65      (void) strcat(scratch, "XXXXXX");
66      mktemp(scratch);
67
68      lid->data = (krb5_pointer) malloc(sizeof(krb5_scc_data));
69      if (lid->data == NULL) {
70           krb5_xfree(lid);
71           return KRB5_CC_NOMEM;
72      }
73
74      ((krb5_scc_data *) lid->data)->filename = (char *)
75           malloc(strlen(scratch) + 1);
76      if (((krb5_scc_data *) lid->data)->filename == NULL) {
77           krb5_xfree(((krb5_scc_data *) lid->data));
78           krb5_xfree(lid);
79           return KRB5_CC_NOMEM;
80      }
81
82      ((krb5_scc_data *) lid->data)->flags = 0;
83      ((krb5_scc_data *) lid->data)->file = 0;
84      
85      /* Set up the filename */
86      strcpy(((krb5_scc_data *) lid->data)->filename, scratch);
87
88      /* Make sure the file name is useable */
89 #if defined(__STDC__) || defined(_WINDOWS)
90      f = fopen (((krb5_scc_data *) lid->data)->filename, "wb+");
91 #else
92      f = fopen (((krb5_scc_data *) lid->data)->filename, "w+");
93 #endif
94      if (!f) {
95              retcode = krb5_scc_interpret (context, errno);
96              goto err_out;
97      } else {
98          unsigned char scc_fvno[2];
99
100          scc_fvno[0] = (unsigned char) (KRB5_SCC_DEFAULT_FVNO >> 8);
101          scc_fvno[1] = (unsigned char) (KRB5_SCC_DEFAULT_FVNO & 0xFF);
102
103          if (!fwrite((char *)scc_fvno, sizeof(scc_fvno), 1, f)) {
104              retcode = krb5_scc_interpret(context, errno);
105              (void) fclose(f);
106              (void) remove(((krb5_scc_data *) lid->data)->filename);
107              goto err_out;
108          }
109          if (fclose(f) == EOF) {
110              retcode = krb5_scc_interpret(context, errno);
111              (void) remove(((krb5_scc_data *) lid->data)->filename);
112              goto err_out;
113          }
114          *id = lid;
115          return KRB5_OK;
116      }
117 err_out:
118      krb5_xfree(((krb5_scc_data *) lid->data)->filename);
119      krb5_xfree(((krb5_scc_data *) lid->data));
120      krb5_xfree(lid);
121      return retcode;
122 }