/ SecurityTool / macOS / db_commands.cpp
db_commands.cpp
  1  /*
  2   * Copyright (c) 2003-2005,2012,2014 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   * 
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   * 
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   * 
 21   * @APPLE_LICENSE_HEADER_END@
 22   *
 23   * db_commands.cpp -- commands to directly manipulate Db's using the DL API.
 24   */
 25  
 26  #include "db_commands.h"
 27  
 28  #include "readline_cssm.h"
 29  #include "security_tool.h"
 30  
 31  #include <stdio.h>
 32  #include <stdlib.h>
 33  #include <unistd.h>
 34  #include <security_cdsa_client/dlclient.h>
 35  
 36  using namespace CssmClient;
 37  
 38  static int
 39  do_db_create(const CSSM_GUID guid, const char *dbname, Boolean do_openparams, Boolean do_autocommit, Boolean do_mode, mode_t mode, Boolean do_version_0_params)
 40  {
 41  	int result = 0;
 42  
 43  	try
 44  	{
 45  		CSSM_APPLEDL_OPEN_PARAMETERS openParameters = { sizeof(CSSM_APPLEDL_OPEN_PARAMETERS),
 46  			(do_version_0_params ? 0u : CSSM_APPLEDL_OPEN_PARAMETERS_VERSION) };
 47  		Cssm cssm;
 48  		Module module(guid, cssm);
 49  		DL dl(module);
 50  		Db db(dl, dbname);
 51  
 52  		if (do_openparams)
 53  		{
 54  			openParameters.autoCommit = do_autocommit;
 55  			if (!do_version_0_params && do_mode)
 56  			{
 57  				openParameters.mask |= kCSSM_APPLEDL_MASK_MODE;
 58  				openParameters.mode = mode;
 59  			}
 60  
 61  			db->openParameters(&openParameters);
 62  		}
 63  
 64  		db->create();
 65  	}
 66  	catch (const CommonError &e)
 67  	{
 68  		OSStatus status = e.osStatus();
 69  		sec_error("CSSM_DbCreate %s: %s", dbname, sec_errstr(status));
 70  	}
 71  	catch (...)
 72  	{
 73  		result = 1;
 74  	}
 75  
 76  	return result;
 77  }
 78  
 79  static int
 80  parse_guid(const char *name, CSSM_GUID *guid)
 81  {
 82  	size_t len = strlen(name);
 83  
 84  	if (!strncmp("dl", name, len))
 85  		*guid = gGuidAppleFileDL;
 86  	else if (!strncmp("cspdl", name, len))
 87  		*guid = gGuidAppleCSPDL;
 88  	else
 89  	{
 90  		sec_error("Invalid guid: %s", name);
 91  		return SHOW_USAGE_MESSAGE;
 92  	}
 93  
 94  	return 0;
 95  }
 96  
 97  
 98  static int
 99  parse_mode(const char *name, mode_t *pmode)
100  {
101  	int result = 0;
102  	mode_t mode = 0;
103  	const char *p;
104  
105  	if (!name || !pmode || *name != '0')
106  	{
107  		result = 2;
108  		goto loser;
109  	}
110  
111  	for (p = name + 1; *p; ++p)
112  	{
113  		if (*p < '0' || *p > '7')
114  		{
115  			result = 2;
116  			goto loser;
117  		}
118  
119  		mode = (mode << 3) + *p - '0';
120  	}
121  
122  	*pmode = mode;
123  	return 0;
124  
125  loser:
126  	sec_error("Invalid mode: %s", name);
127  	return result;
128  }
129  
130  int
131  db_create(int argc, char * const *argv)
132  {
133  	int free_dbname = 0;
134  	char *dbname = NULL;
135  	int ch, result = 0;
136  	bool do_autocommit = true, do_mode = false;
137  	bool do_openparams = false, do_version_0_params = false;
138  	mode_t mode = 0666;
139  	CSSM_GUID guid = gGuidAppleFileDL;
140  
141  	while ((ch = getopt(argc, argv, "0ahg:m:o")) != -1)
142  	{
143  		switch  (ch)
144  		{
145  		case '0':
146  			do_version_0_params = true;
147  			do_openparams = true;
148  			break;
149  		case 'a':
150  			do_autocommit = false;
151  			do_openparams = true;
152  			break;
153  		case 'g':
154  			result = parse_guid(optarg, &guid);
155  			if (result)
156  				goto loser;
157  			break;
158  		case 'm':
159  			result = parse_mode(optarg, &mode);
160  			if (result)
161  				goto loser;
162  			do_mode = true;
163  			do_openparams = true;
164  			break;
165  		case 'o':
166  			do_openparams = true;
167  			break;
168  		case '?':
169  		default:
170  			return SHOW_USAGE_MESSAGE;
171  		}
172  	}
173  
174  	argc -= optind;
175  	argv += optind;
176  
177  	if (argc > 0)
178  		dbname = *argv;
179  	else
180  	{
181  		fprintf(stderr, "db to create: ");
182  		dbname = readline(NULL, 0);
183  		if (!dbname)
184  		{
185  			result = -1;
186  			goto loser;
187  		}
188  
189  		free_dbname = 1;
190  		if (*dbname == '\0')
191  			goto loser;
192  	}
193  
194  	do
195  	{
196  		result = do_db_create(guid, dbname, do_openparams, do_autocommit, do_mode, mode, do_version_0_params);
197  		if (result)
198  			goto loser;
199  
200  		argc--;
201  		argv++;
202  		dbname = *argv;
203  	} while (argc > 0);
204  
205  loser:
206  	if (free_dbname)
207  		free(dbname);
208  
209  	return result;
210  }